summaryrefslogtreecommitdiff
path: root/raveos-calamares-module
diff options
context:
space:
mode:
authorNippy <nippy@Nippy-Mac-mini.local>2026-11-01 18:13:54 +0100
committerNippy <nippy@Nippy-Mac-mini.local>2026-11-01 18:13:54 +0100
commita64ef966534f8dba6af889ba4bfce15691bfc85b (patch)
treeb30f284d05b80fa115569ab220deae13797fad6f /raveos-calamares-module
parent919f977b40016f588b0c8532c8a57f6035056b95 (diff)
downloadRaveOS-PKGBUILD-a64ef966534f8dba6af889ba4bfce15691bfc85b.tar.gz
RaveOS-PKGBUILD-a64ef966534f8dba6af889ba4bfce15691bfc85b.zip
új telepítő
Diffstat (limited to 'raveos-calamares-module')
-rw-r--r--raveos-calamares-module/PKGBUILD4
-rw-r--r--raveos-calamares-module/README.md9
-rw-r--r--raveos-calamares-module/common/RaveBrandingQml.h13
-rw-r--r--raveos-calamares-module/desktopselect/desktopselect.conf10
-rw-r--r--raveos-calamares-module/desktopselect/ui/desktopselect.qml34
-rw-r--r--raveos-calamares-module/raveusers/RaveUsersBackend.cpp18
-rw-r--r--raveos-calamares-module/raveusers/RaveUsersBackend.h5
-rw-r--r--raveos-calamares-module/raveusers/RaveUsersJobs.cpp8
-rw-r--r--raveos-calamares-module/raveusers/RaveUsersViewStep.cpp48
-rw-r--r--raveos-calamares-module/raveusers/RaveUsersViewStep.h1
-rw-r--r--raveos-calamares-module/raveusers/ui/PasswordField.qml34
-rw-r--r--raveos-calamares-module/raveusers/ui/Translations.qml4
-rw-r--r--raveos-calamares-module/raveusers/ui/raveusers.qml126
-rw-r--r--raveos-calamares-module/welcome/CMakeLists.txt9
-rw-r--r--raveos-calamares-module/welcome/RaveBillentyuzet.cpp81
-rw-r--r--raveos-calamares-module/welcome/RaveBillentyuzet.h16
-rw-r--r--raveos-calamares-module/welcome/RaveWelcomeViewStep.cpp191
-rw-r--r--raveos-calamares-module/welcome/RaveWelcomeViewStep.h14
-rw-r--r--raveos-calamares-module/welcome/ravewelcome.conf7
-rw-r--r--raveos-calamares-module/wifi/CMakeLists.txt1
-rw-r--r--raveos-calamares-module/wifi/NetworkManager.cpp95
-rw-r--r--raveos-calamares-module/wifi/NetworkManager.h11
-rw-r--r--raveos-calamares-module/wifi/WifiViewStep.cpp24
-rw-r--r--raveos-calamares-module/wifi/WifiViewStep.h1
-rw-r--r--raveos-calamares-module/wifi/ui/Style.qml161
-rw-r--r--raveos-calamares-module/wifi/ui/Translations.qml219
-rw-r--r--raveos-calamares-module/wifi/ui/qmldir1
-rw-r--r--raveos-calamares-module/wifi/ui/wifi.qml655
28 files changed, 945 insertions, 855 deletions
diff --git a/raveos-calamares-module/PKGBUILD b/raveos-calamares-module/PKGBUILD
index 186946e..952a702 100644
--- a/raveos-calamares-module/PKGBUILD
+++ b/raveos-calamares-module/PKGBUILD
@@ -1,7 +1,7 @@
# Maintainer: nippy <nippy@tuta.io>
pkgname=raveos-calamares-module
pkgver=2.0.0
-pkgrel=38
+pkgrel=39
pkgdesc="RaveOS Calamares modules: Wi-Fi, Welcome, Desktop Selector, Users"
arch=('x86_64')
options=('!debug')
@@ -9,7 +9,7 @@ url="https://git.rp1.hu/RaveOS"
license=('GPL')
makedepends=('cmake' 'qt6-tools' 'kcoreaddons' 'calamares' 'libxcrypt')
-depends=('qt6-base' 'qt6-declarative' 'networkmanager' 'xorg-setxkbmap' 'calamares')
+depends=('qt6-base' 'qt6-declarative' 'networkmanager' 'xorg-setxkbmap' 'calamares' 'libxkbcommon')
source=()
sha256sums=()
diff --git a/raveos-calamares-module/README.md b/raveos-calamares-module/README.md
index f670233..20957ae 100644
--- a/raveos-calamares-module/README.md
+++ b/raveos-calamares-module/README.md
@@ -1,5 +1,8 @@
-RaveOS Calamares Wi-Fi Modul
+RaveOS Calamares modulok
-Calamares viewmodule WiFi kapcsolat kezeléséhez live ISO telepítés közben.
-..
+- ravewelcome: nyelvválasztó első lépés
+- wifi: Wi-Fi kapcsolat a live rendszeren
+- raveusers: felhasználó, gépnév, jelszó, automatikus bejelentkezés
+- desktopselect: asztali környezet választó
+A QML felületek a branding mappából regisztrált RaveOS típusokat használják (common/RaveBrandingQml.h).
diff --git a/raveos-calamares-module/common/RaveBrandingQml.h b/raveos-calamares-module/common/RaveBrandingQml.h
new file mode 100644
index 0000000..6ad3453
--- /dev/null
+++ b/raveos-calamares-module/common/RaveBrandingQml.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <Branding.h>
+
+#include <QQmlEngine>
+
+inline void addRaveBrandingImportPath( QQmlEngine* engine )
+{
+ if ( const auto* branding = Calamares::Branding::instance() )
+ {
+ engine->addImportPath( branding->componentDirectory() );
+ }
+}
diff --git a/raveos-calamares-module/desktopselect/desktopselect.conf b/raveos-calamares-module/desktopselect/desktopselect.conf
index 7b9939f..d724605 100644
--- a/raveos-calamares-module/desktopselect/desktopselect.conf
+++ b/raveos-calamares-module/desktopselect/desktopselect.conf
@@ -4,7 +4,7 @@ mandatory_packages:
- raveos-keyring
- raveos-mirrorlist
- raveos-welcome
- - raveos-app-installer
+ - raveos-center
- raveos-support
- brave-origin-bin
- noto-fonts
@@ -59,7 +59,7 @@ desktops:
badge_hu: "STABIL"
badge_de: "STABIL"
badge_en: "STABLE"
- badge_color: "#2e7d32"
+ badge_color: "#62a052"
packages:
- plasma-desktop
- plasma-wayland-protocols
@@ -97,7 +97,7 @@ desktops:
badge_hu: "STABIL"
badge_de: "STABIL"
badge_en: "STABLE"
- badge_color: "#2e7d32"
+ badge_color: "#62a052"
packages:
- gnome-session
- gnome-console
@@ -135,7 +135,7 @@ desktops:
badge_hu: "HAMAROSAN"
badge_de: "BALD"
badge_en: "SOON"
- badge_color: "#e65100"
+ badge_color: "#d9a441"
available: false
- name: "Hyprland"
@@ -145,7 +145,7 @@ desktops:
badge_hu: "STABIL"
badge_de: "STABIL"
badge_en: "STABLE"
- badge_color: "#2e7d32"
+ badge_color: "#62a052"
packages:
- hyprland
- aquamarine
diff --git a/raveos-calamares-module/desktopselect/ui/desktopselect.qml b/raveos-calamares-module/desktopselect/ui/desktopselect.qml
index 4fd0318..9d717a2 100644
--- a/raveos-calamares-module/desktopselect/ui/desktopselect.qml
+++ b/raveos-calamares-module/desktopselect/ui/desktopselect.qml
@@ -5,7 +5,7 @@ import "." as DesktopSelectModule
Rectangle {
id: root
- color: "#404040"
+ color: "#1a1b1d"
// Function to update language - called from C++
function updateLanguage() {
@@ -21,8 +21,9 @@ Rectangle {
Rectangle {
anchors.fill: parent
anchors.margins: 20
- color: "#2B2B2B"
- radius: 10
+ color: "#232427"
+ border.color: "#34363a"
+ border.width: 1
ColumnLayout {
anchors.fill: parent
@@ -34,22 +35,21 @@ Rectangle {
text: DesktopSelectModule.Translations.title
font.pixelSize: 24
font.bold: true
- color: "#ffffff"
+ color: "#e8e8e6"
}
// Figyelmeztető banner
Rectangle {
Layout.fillWidth: true
height: 50
- color: "#1e1e1e"
- border.color: "#e67e22"
- border.width: 2
- radius: 6
+ color: "#2e2a20"
+ border.color: "#d9a441"
+ border.width: 1
Text {
anchors.centerIn: parent
text: DesktopSelectModule.Translations.banner
- color: "#e0e0e0"
+ color: "#f0dcb0"
font.pixelSize: 13
}
}
@@ -67,13 +67,12 @@ Rectangle {
id: card
width: desktopList.width
height: 78
- radius: 8
property bool selectable: modelData.available !== false
- color: !selectable ? "#2a2a2a" : (backend.selectedIndex === index ? "#2a4a2a" : "#333333")
- border.color: !selectable ? "#444444" : (backend.selectedIndex === index ? "#5cb85c" : "#555555")
- border.width: 2
+ color: !selectable ? "#1f2022" : (backend.selectedIndex === index ? "#24301f" : "#1a1b1d")
+ border.color: !selectable ? "#34363a" : (backend.selectedIndex === index ? "#62a052" : "#44464b")
+ border.width: backend.selectedIndex === index ? 2 : 1
RowLayout {
anchors.fill: parent
@@ -87,14 +86,14 @@ Rectangle {
Text {
text: modelData.name || ""
- color: card.selectable ? "#ffffff" : "#9a9a9a"
+ color: card.selectable ? "#e8e8e6" : "#9a9ca1"
font.pixelSize: 15
font.bold: true
}
Text {
text: modelData.description || ""
- color: card.selectable ? "#b2b2b2" : "#8a8a8a"
+ color: card.selectable ? "#b7b9bd" : "#7d7f84"
font.pixelSize: 12
width: parent.width
elide: Text.ElideRight
@@ -104,14 +103,13 @@ Rectangle {
Rectangle {
width: badgeText.implicitWidth + 20
height: 28
- radius: 4
- color: modelData.badge_color || "#555555"
+ color: modelData.badge_color || "#44464b"
Text {
id: badgeText
anchors.centerIn: parent
text: modelData.badge || ""
- color: "#ffffff"
+ color: "#1a1b1d"
font.pixelSize: 11
font.bold: true
}
diff --git a/raveos-calamares-module/raveusers/RaveUsersBackend.cpp b/raveos-calamares-module/raveusers/RaveUsersBackend.cpp
index 6f8eea6..538732f 100644
--- a/raveos-calamares-module/raveusers/RaveUsersBackend.cpp
+++ b/raveos-calamares-module/raveusers/RaveUsersBackend.cpp
@@ -75,7 +75,7 @@ RaveUsersBackend::hostnameStatus() const
QString
RaveUsersBackend::passwordStatus() const
{
- if ( m_password.isEmpty() )
+ if ( m_password.isEmpty() || m_passwordSecondary.isEmpty() )
{
return QString();
}
@@ -93,7 +93,7 @@ RaveUsersBackend::rootPasswordStatus() const
{
return QString();
}
- if ( m_rootPassword.isEmpty() )
+ if ( m_rootPassword.isEmpty() || m_rootPasswordSecondary.isEmpty() )
{
return QString();
}
@@ -115,13 +115,13 @@ RaveUsersBackend::isReady() const
{
return false;
}
- if ( m_password.isEmpty() || !passwordStatus().isEmpty() )
+ if ( m_password.isEmpty() || m_password != m_passwordSecondary )
{
return false;
}
if ( m_setRootPassword && !m_reuseRootPassword )
{
- if ( m_rootPassword.isEmpty() || !rootPasswordStatus().isEmpty() )
+ if ( m_rootPassword.isEmpty() || m_rootPassword != m_rootPasswordSecondary )
{
return false;
}
@@ -231,6 +231,16 @@ RaveUsersBackend::setReuseRootPassword( bool b )
}
void
+RaveUsersBackend::setAutoLogin( bool b )
+{
+ if ( b != m_autoLogin )
+ {
+ m_autoLogin = b;
+ emit autoLoginChanged();
+ }
+}
+
+void
RaveUsersBackend::checkReady()
{
const bool ready = isReady();
diff --git a/raveos-calamares-module/raveusers/RaveUsersBackend.h b/raveos-calamares-module/raveusers/RaveUsersBackend.h
index 4e06f47..06a6fad 100644
--- a/raveos-calamares-module/raveusers/RaveUsersBackend.h
+++ b/raveos-calamares-module/raveusers/RaveUsersBackend.h
@@ -17,6 +17,7 @@ class RaveUsersBackend : public QObject
Q_PROPERTY( bool ready READ isReady NOTIFY readyChanged )
Q_PROPERTY( bool reuseRootPassword READ reuseRootPassword NOTIFY reuseRootPasswordChanged )
Q_PROPERTY( bool rootReuseVisible READ rootReuseVisible CONSTANT )
+ Q_PROPERTY( bool autoLogin READ autoLogin NOTIFY autoLoginChanged )
public:
explicit RaveUsersBackend( QObject* parent = nullptr );
@@ -29,6 +30,7 @@ public:
QString rootPasswordStatus() const;
bool isReady() const;
bool reuseRootPassword() const { return m_reuseRootPassword; }
+ bool autoLogin() const { return m_autoLogin; }
bool rootReuseVisible() const { return m_setRootPassword; }
QString userPassword() const { return m_password; }
@@ -48,6 +50,7 @@ public:
Q_INVOKABLE void setRootPasswordText( const QString& s );
Q_INVOKABLE void setRootPasswordSecondaryText( const QString& s );
Q_INVOKABLE void setReuseRootPassword( bool b );
+ Q_INVOKABLE void setAutoLogin( bool b );
void setForbiddenLoginNames( const QStringList& names ) { m_forbiddenLoginNames = names; }
void setForbiddenHostNames( const QStringList& names ) { m_forbiddenHostNames = names; }
@@ -64,6 +67,7 @@ signals:
void statusChanged();
void readyChanged();
void reuseRootPasswordChanged();
+ void autoLoginChanged();
private:
void checkReady();
@@ -76,6 +80,7 @@ private:
QString m_rootPasswordSecondary;
bool m_customHostname = false;
bool m_reuseRootPassword = true;
+ bool m_autoLogin = false;
bool m_setRootPassword = true;
QStringList m_forbiddenLoginNames;
diff --git a/raveos-calamares-module/raveusers/RaveUsersJobs.cpp b/raveos-calamares-module/raveusers/RaveUsersJobs.cpp
index 1923c38..18af3e7 100644
--- a/raveos-calamares-module/raveusers/RaveUsersJobs.cpp
+++ b/raveos-calamares-module/raveusers/RaveUsersJobs.cpp
@@ -38,7 +38,7 @@ RaveUsersCreateUserJob::prettyName() const
QString
RaveUsersCreateUserJob::prettyStatusMessage() const
{
- return tr( "Creating user %1…", "@status" ).arg( m_backend->username() );
+ return tr( "Creating user %1...", "@status" ).arg( m_backend->username() );
}
Calamares::JobResult
@@ -106,7 +106,7 @@ RaveUsersSetPasswordJob::prettyName() const
QString
RaveUsersSetPasswordJob::prettyStatusMessage() const
{
- return tr( "Setting password for user %1…", "@status" ).arg( m_userName );
+ return tr( "Setting password for user %1...", "@status" ).arg( m_userName );
}
static QString
@@ -210,7 +210,7 @@ RaveUsersSetupSudoJob::RaveUsersSetupSudoJob( const QString& group, bool configu
QString
RaveUsersSetupSudoJob::prettyName() const
{
- return tr( "Configuring sudo users…", "@status" );
+ return tr( "Configuring sudo users...", "@status" );
}
Calamares::JobResult
@@ -250,7 +250,7 @@ RaveUsersSetupGroupsJob::RaveUsersSetupGroupsJob( const QStringList& groups )
QString
RaveUsersSetupGroupsJob::prettyName() const
{
- return tr( "Preparing groups…", "@status" );
+ return tr( "Preparing groups...", "@status" );
}
Calamares::JobResult
diff --git a/raveos-calamares-module/raveusers/RaveUsersViewStep.cpp b/raveos-calamares-module/raveusers/RaveUsersViewStep.cpp
index 4014429..fbcd765 100644
--- a/raveos-calamares-module/raveusers/RaveUsersViewStep.cpp
+++ b/raveos-calamares-module/raveusers/RaveUsersViewStep.cpp
@@ -52,6 +52,44 @@ RaveUsersViewStep::prettyName() const
return tr( "User" );
}
+QString
+RaveUsersViewStep::prettyStatus() const
+{
+ if ( !m_backend || m_backend->username().isEmpty() )
+ {
+ return QString();
+ }
+ const QString locale = getLocale();
+ QString userLabel = QStringLiteral( "User" );
+ QString hostLabel = QStringLiteral( "Computer name" );
+ QString autoLabel = QStringLiteral( "Automatic login" );
+ QString yes = QStringLiteral( "yes" );
+ QString no = QStringLiteral( "no" );
+ if ( locale.startsWith( QLatin1String( "hu" ) ) )
+ {
+ userLabel = QStringLiteral( "Felhasználó" );
+ hostLabel = QStringLiteral( "Gép neve" );
+ autoLabel = QStringLiteral( "Automatikus bejelentkezés" );
+ yes = QStringLiteral( "igen" );
+ no = QStringLiteral( "nem" );
+ }
+ else if ( locale.startsWith( QLatin1String( "de" ) ) )
+ {
+ userLabel = QStringLiteral( "Benutzer" );
+ hostLabel = QStringLiteral( "Computername" );
+ autoLabel = QStringLiteral( "Automatische Anmeldung" );
+ yes = QStringLiteral( "ja" );
+ no = QStringLiteral( "nein" );
+ }
+ return QStringLiteral( "%1: <b>%2</b><br/>%3: <b>%4</b><br/>%5: <b>%6</b>" )
+ .arg( userLabel,
+ m_backend->username().toHtmlEscaped(),
+ hostLabel,
+ m_backend->hostname().toHtmlEscaped(),
+ autoLabel,
+ m_backend->autoLogin() ? yes : no );
+}
+
void
RaveUsersViewStep::buildWidget()
{
@@ -62,7 +100,7 @@ RaveUsersViewStep::buildWidget()
m_quickWidget = new QQuickWidget();
m_quickWidget->setResizeMode( QQuickWidget::SizeRootObjectToView );
- m_quickWidget->setClearColor( QColor( 0x40, 0x40, 0x40 ) );
+ m_quickWidget->setClearColor( QColor( 0x1a, 0x1b, 0x1d ) );
QString modulePath = QStringLiteral( "/usr/lib/calamares/modules/raveusers/ui" );
if ( !QDir( modulePath ).exists() )
@@ -189,6 +227,14 @@ RaveUsersViewStep::onLeave()
gs->insert( "password", Calamares::String::obscure( m_backend->userPassword() ) );
gs->insert( "setRootPassword", m_backend->rootReuseVisible() );
gs->insert( "reuseRootPassword", m_backend->reuseRootPassword() );
+ if ( m_backend->autoLogin() )
+ {
+ gs->insert( "autoLoginUser", username );
+ }
+ else
+ {
+ gs->remove( "autoLoginUser" );
+ }
}
void
diff --git a/raveos-calamares-module/raveusers/RaveUsersViewStep.h b/raveos-calamares-module/raveusers/RaveUsersViewStep.h
index 67593ac..ed096cc 100644
--- a/raveos-calamares-module/raveusers/RaveUsersViewStep.h
+++ b/raveos-calamares-module/raveusers/RaveUsersViewStep.h
@@ -21,6 +21,7 @@ public:
~RaveUsersViewStep() override;
QString prettyName() const override;
+ QString prettyStatus() const override;
QWidget* widget() override;
bool isNextEnabled() const override;
diff --git a/raveos-calamares-module/raveusers/ui/PasswordField.qml b/raveos-calamares-module/raveusers/ui/PasswordField.qml
index 0dffb49..7c9955b 100644
--- a/raveos-calamares-module/raveusers/ui/PasswordField.qml
+++ b/raveos-calamares-module/raveusers/ui/PasswordField.qml
@@ -10,24 +10,38 @@ TextField {
leftPadding: 14
rightPadding: 46
echoMode: reveal ? TextInput.Normal : TextInput.Password
- color: "#ffffff"
- placeholderTextColor: "#5b6270"
+ color: "#e8e8e6"
+ placeholderTextColor: "#9a9ca1"
font.pixelSize: 15
background: Rectangle {
- radius: 7
- color: "#303030"
- border.color: field.activeFocus ? "#3d7839" : "#303030"
+ color: "#232427"
+ border.color: field.activeFocus ? "#62a052" : "#44464b"
border.width: field.activeFocus ? 1.5 : 1
}
- Text {
- text: "\uD83D\uDC41"
- font.pixelSize: 16
- color: field.reveal ? "#3d7839" : "#9ca3af"
+ Canvas {
+ width: 20
+ height: 20
anchors.right: parent.right
- anchors.rightMargin: 14
+ anchors.rightMargin: 12
anchors.verticalCenter: parent.verticalCenter
+ property bool aktiv: field.reveal
+ onAktivChanged: requestPaint()
+ onPaint: {
+ var c = getContext("2d")
+ c.reset()
+ c.strokeStyle = aktiv ? "#62a052" : "#9a9ca1"
+ c.lineWidth = 1.8
+ c.beginPath()
+ c.moveTo(2, 10)
+ c.quadraticCurveTo(10, 2, 18, 10)
+ c.quadraticCurveTo(10, 18, 2, 10)
+ c.stroke()
+ c.beginPath()
+ c.arc(10, 10, 2.8, 0, 2 * Math.PI)
+ c.stroke()
+ }
}
MouseArea {
diff --git a/raveos-calamares-module/raveusers/ui/Translations.qml b/raveos-calamares-module/raveusers/ui/Translations.qml
index cb267b4..ef2bb67 100644
--- a/raveos-calamares-module/raveusers/ui/Translations.qml
+++ b/raveos-calamares-module/raveusers/ui/Translations.qml
@@ -12,6 +12,7 @@ QtObject {
property string passwordPlaceholder: "Password"
property string passwordConfirmLabel: "Confirm password"
property string reuseRootLabel: "Use the same password for the administrator (root)"
+ property string autoLoginLabel: "Log in automatically without a password"
property string rootPasswordLabel: "Root password"
property string rootPasswordPlaceholder: "Root password"
property string rootPasswordConfirmLabel: "Confirm root password"
@@ -26,6 +27,7 @@ QtObject {
passwordPlaceholder = "Jelszó"
passwordConfirmLabel = "Jelszó megerősítése"
reuseRootLabel = "Ugyanaz a jelszó az adminisztrátorhoz (root)"
+ autoLoginLabel = "Automatikus bejelentkezés jelszó nélkül"
rootPasswordLabel = "Root jelszó"
rootPasswordPlaceholder = "Root jelszó"
rootPasswordConfirmLabel = "Root jelszó megerősítése"
@@ -38,6 +40,7 @@ QtObject {
passwordPlaceholder = "Passwort"
passwordConfirmLabel = "Passwort bestätigen"
reuseRootLabel = "Dasselbe Passwort für den Administrator (root)"
+ autoLoginLabel = "Automatisch ohne Passwort anmelden"
rootPasswordLabel = "Root-Passwort"
rootPasswordPlaceholder = "Root-Passwort"
rootPasswordConfirmLabel = "Root-Passwort bestätigen"
@@ -50,6 +53,7 @@ QtObject {
passwordPlaceholder = "Password"
passwordConfirmLabel = "Confirm password"
reuseRootLabel = "Use the same password for the administrator (root)"
+ autoLoginLabel = "Log in automatically without a password"
rootPasswordLabel = "Root password"
rootPasswordPlaceholder = "Root password"
rootPasswordConfirmLabel = "Confirm root password"
diff --git a/raveos-calamares-module/raveusers/ui/raveusers.qml b/raveos-calamares-module/raveusers/ui/raveusers.qml
index 25e090f..030f3f4 100644
--- a/raveos-calamares-module/raveusers/ui/raveusers.qml
+++ b/raveos-calamares-module/raveusers/ui/raveusers.qml
@@ -5,18 +5,16 @@ import "." as RaveUsersModule
Rectangle {
id: root
- color: "#2B2B2B"
- radius: 14
+ color: "#1a1b1d"
- readonly property color cCardBg: "#20232a"
- readonly property color cCardBorder: "#333947"
- readonly property color cInputBg: "#303030"
- readonly property color cInputBorder: "#303030"
- readonly property color cAccentGreen: "#3d7839"
- readonly property color cTextWhite: "#ffffff"
- readonly property color cTextMuted: "#8b93a3"
- readonly property color cTextFaint: "#5b6270"
- readonly property color cErrorRed: "#ff6b6b"
+ readonly property color cCardBorder: "#34363a"
+ readonly property color cInputBg: "#232427"
+ readonly property color cInputBorder: "#44464b"
+ readonly property color cAccentGreen: "#62a052"
+ readonly property color cTextWhite: "#e8e8e6"
+ readonly property color cTextMuted: "#b7b9bd"
+ readonly property color cTextFaint: "#9a9ca1"
+ readonly property color cErrorRed: "#d9a441"
property bool showUserPassword: false
property bool showRootPassword: false
@@ -29,20 +27,64 @@ Rectangle {
RaveUsersModule.Translations.setLanguage(systemLocale)
}
+ component RegiJelolo: CheckBox {
+ id: jelolo
+
+ indicator: Rectangle {
+ implicitWidth: 20
+ implicitHeight: 20
+ x: jelolo.leftPadding
+ y: parent.height / 2 - height / 2
+ color: jelolo.checked ? cAccentGreen : cInputBg
+ border.color: jelolo.checked ? cAccentGreen : cInputBorder
+ border.width: 1
+
+ Canvas {
+ anchors.fill: parent
+ visible: jelolo.checked
+ onVisibleChanged: if (visible) requestPaint()
+ onPaint: {
+ var c = getContext("2d")
+ c.reset()
+ c.strokeStyle = "#1a1b1d"
+ c.lineWidth = 2.5
+ c.beginPath()
+ c.moveTo(5, 10)
+ c.lineTo(9, 14)
+ c.lineTo(15, 6)
+ c.stroke()
+ }
+ }
+ }
+
+ contentItem: Text {
+ text: jelolo.text
+ color: cTextWhite
+ font.pixelSize: 14
+ verticalAlignment: Text.AlignVCenter
+ leftPadding: jelolo.indicator.width + 12
+ }
+ }
+
ColumnLayout {
anchors.fill: parent
anchors.margins: 40
spacing: 0
- Item {
+ Flickable {
+ id: gorgeto
Layout.fillWidth: true
Layout.fillHeight: true
+ contentHeight: tartalom.implicitHeight + 20
+ clip: true
+ boundsBehavior: Flickable.StopAtBounds
+ ScrollBar.vertical: ScrollBar {}
ColumnLayout {
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: parent.top
- anchors.topMargin: 10
- width: Math.min(parent.width - 40, 540)
+ id: tartalom
+ x: (gorgeto.width - width) / 2
+ y: 10
+ width: Math.min(gorgeto.width - 40, 540)
spacing: 16
Image {
@@ -81,7 +123,7 @@ Rectangle {
Text {
text: RaveUsersModule.Translations.usernameLabel
- color: "#c7ccd6"
+ color: cTextMuted
font.pixelSize: 14
font.weight: Font.Medium
}
@@ -95,10 +137,9 @@ Rectangle {
text: backend.username
placeholderText: "raveuser"
color: cTextWhite
- placeholderTextColor: "#5b6270"
+ placeholderTextColor: cTextFaint
font.pixelSize: 15
background: Rectangle {
- radius: 7
color: cInputBg
border.color: usernameField.activeFocus ? cAccentGreen : cInputBorder
border.width: usernameField.activeFocus ? 1.5 : 1
@@ -120,7 +161,7 @@ Rectangle {
Text {
text: RaveUsersModule.Translations.hostnameLabel
- color: "#c7ccd6"
+ color: cTextMuted
font.pixelSize: 14
font.weight: Font.Medium
}
@@ -134,10 +175,9 @@ Rectangle {
text: backend.hostname
placeholderText: "raveos-pc"
color: cTextWhite
- placeholderTextColor: "#5b6270"
+ placeholderTextColor: cTextFaint
font.pixelSize: 15
background: Rectangle {
- radius: 7
color: cInputBg
border.color: hostnameField.activeFocus ? cAccentGreen : cInputBorder
border.width: hostnameField.activeFocus ? 1.5 : 1
@@ -159,7 +199,7 @@ Rectangle {
Text {
text: RaveUsersModule.Translations.passwordLabel
- color: "#c7ccd6"
+ color: cTextMuted
font.pixelSize: 14
font.weight: Font.Medium
}
@@ -202,41 +242,19 @@ Rectangle {
opacity: 0.6
}
- CheckBox {
- id: reuseRootCheck
+ RegiJelolo {
+ Layout.fillWidth: true
+ text: RaveUsersModule.Translations.autoLoginLabel
+ checked: backend.autoLogin
+ onToggled: backend.setAutoLogin(checked)
+ }
+
+ RegiJelolo {
Layout.fillWidth: true
visible: backend.rootReuseVisible
text: RaveUsersModule.Translations.reuseRootLabel
checked: backend.reuseRootPassword
onToggled: backend.setReuseRootPassword(checked)
-
- indicator: Rectangle {
- implicitWidth: 20
- implicitHeight: 20
- x: reuseRootCheck.leftPadding
- y: parent.height / 2 - height / 2
- radius: 4
- color: reuseRootCheck.checked ? cAccentGreen : cInputBg
- border.color: reuseRootCheck.checked ? cAccentGreen : cInputBorder
- border.width: 1
-
- Text {
- anchors.centerIn: parent
- text: "\u2713"
- font.pixelSize: 14
- font.bold: true
- color: "#0f1713"
- visible: reuseRootCheck.checked
- }
- }
-
- contentItem: Text {
- text: reuseRootCheck.text
- color: "#d7dbe2"
- font.pixelSize: 14
- verticalAlignment: Text.AlignVCenter
- leftPadding: reuseRootCheck.indicator.width + 12
- }
}
ColumnLayout {
@@ -246,7 +264,7 @@ Rectangle {
Text {
text: RaveUsersModule.Translations.rootPasswordLabel
- color: "#c7ccd6"
+ color: cTextMuted
font.pixelSize: 14
font.weight: Font.Medium
Layout.topMargin: 4
diff --git a/raveos-calamares-module/welcome/CMakeLists.txt b/raveos-calamares-module/welcome/CMakeLists.txt
index 9d28587..063f23b 100644
--- a/raveos-calamares-module/welcome/CMakeLists.txt
+++ b/raveos-calamares-module/welcome/CMakeLists.txt
@@ -1,17 +1,22 @@
-find_package(Qt6 REQUIRED COMPONENTS Core Widgets)
+find_package(Qt6 REQUIRED COMPONENTS Core Widgets Qml)
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(XKBCOMMON REQUIRED IMPORTED_TARGET xkbcommon)
calamares_add_plugin(ravewelcome
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
RaveWelcomeViewStep.cpp
+ RaveBillentyuzet.cpp
LINK_LIBRARIES
Qt6::Core
Qt6::Widgets
+ Qt6::Qml
+ PkgConfig::XKBCOMMON
Calamares::calamares
)
install(
- FILES module.desc ravewelcome.conf
+ FILES module.desc
DESTINATION lib/calamares/modules/ravewelcome
)
diff --git a/raveos-calamares-module/welcome/RaveBillentyuzet.cpp b/raveos-calamares-module/welcome/RaveBillentyuzet.cpp
new file mode 100644
index 0000000..aeb1205
--- /dev/null
+++ b/raveos-calamares-module/welcome/RaveBillentyuzet.cpp
@@ -0,0 +1,81 @@
+#include "RaveBillentyuzet.h"
+
+#include <QQmlEngine>
+
+#include <xkbcommon/xkbcommon.h>
+
+namespace
+{
+constexpr int EvdevEltolas = 8;
+
+const QList< QList< int > >& sorKodok()
+{
+ static const QList< QList< int > > kodok {
+ { 41, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
+ { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 },
+ { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 43 },
+ { 86, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 },
+ };
+ return kodok;
+}
+}
+
+QVariantList
+RaveBillentyuzet::gombok( const QString& layout, const QString& variant ) const
+{
+ QVariantList sorok;
+ if ( layout.isEmpty() )
+ {
+ return sorok;
+ }
+
+ xkb_context* context = xkb_context_new( XKB_CONTEXT_NO_FLAGS );
+ if ( !context )
+ {
+ return sorok;
+ }
+
+ const QByteArray layoutBytes = layout.toUtf8();
+ const QByteArray variantBytes = variant.toUtf8();
+ xkb_rule_names names {};
+ names.rules = "evdev";
+ names.model = "pc105";
+ names.layout = layoutBytes.constData();
+ names.variant = variantBytes.isEmpty() ? nullptr : variantBytes.constData();
+
+ xkb_keymap* keymap = xkb_keymap_new_from_names( context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS );
+ if ( !keymap )
+ {
+ xkb_context_unref( context );
+ return sorok;
+ }
+ xkb_state* state = xkb_state_new( keymap );
+
+ for ( const auto& sor : sorKodok() )
+ {
+ QVariantList cimkek;
+ for ( int kod : sor )
+ {
+ char buffer[ 16 ] = {};
+ xkb_state_key_get_utf8( state, static_cast< xkb_keycode_t >( kod + EvdevEltolas ), buffer, sizeof( buffer ) );
+ cimkek << QString::fromUtf8( buffer ).toUpper();
+ }
+ sorok << QVariant( cimkek );
+ }
+
+ xkb_state_unref( state );
+ xkb_keymap_unref( keymap );
+ xkb_context_unref( context );
+ return sorok;
+}
+
+void
+RaveBillentyuzet::regisztral()
+{
+ if ( qmlTypeId( "RaveOSNative", 1, 0, "Billentyuzet" ) >= 0 )
+ {
+ return;
+ }
+ qmlRegisterSingletonType< RaveBillentyuzet >(
+ "RaveOSNative", 1, 0, "Billentyuzet", []( QQmlEngine*, QJSEngine* ) -> QObject* { return new RaveBillentyuzet; } );
+}
diff --git a/raveos-calamares-module/welcome/RaveBillentyuzet.h b/raveos-calamares-module/welcome/RaveBillentyuzet.h
new file mode 100644
index 0000000..4a6b662
--- /dev/null
+++ b/raveos-calamares-module/welcome/RaveBillentyuzet.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <QObject>
+#include <QVariantList>
+
+class RaveBillentyuzet : public QObject
+{
+ Q_OBJECT
+
+public:
+ using QObject::QObject;
+
+ Q_INVOKABLE QVariantList gombok( const QString& layout, const QString& variant ) const;
+
+ static void regisztral();
+};
diff --git a/raveos-calamares-module/welcome/RaveWelcomeViewStep.cpp b/raveos-calamares-module/welcome/RaveWelcomeViewStep.cpp
index c2d58c7..2f7c1ea 100644
--- a/raveos-calamares-module/welcome/RaveWelcomeViewStep.cpp
+++ b/raveos-calamares-module/welcome/RaveWelcomeViewStep.cpp
@@ -1,25 +1,64 @@
#include "RaveWelcomeViewStep.h"
-#include <QComboBox>
+#include "RaveBillentyuzet.h"
+
+#include <QButtonGroup>
#include <QFrame>
+#include <QGridLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLocale>
#include <QPainter>
#include <QProcess>
#include <QPixmap>
-#include <QResizeEvent>
+#include <QPushButton>
#include <QVBoxLayout>
#include <Branding.h>
#include <GlobalStorage.h>
#include <JobQueue.h>
+#include <ViewManager.h>
#include <locale/Translation.h>
-#include <locale/TranslationsModel.h>
#include <utils/Retranslator.h>
CALAMARES_PLUGIN_FACTORY_DEFINITION(RaveWelcomeViewStepFactory, registerPlugin<RaveWelcomeViewStep>();)
+namespace
+{
+struct LanguageTexts
+{
+ QString title;
+ QString next;
+ QString installer;
+};
+
+LanguageTexts textsFor(const QString& localeId)
+{
+ if (localeId.startsWith(QLatin1String("hu")))
+ return { QStringLiteral("VÁLASSZ NYELVET"), QStringLiteral("Tovább"), QStringLiteral("TELEPÍTŐ") };
+ if (localeId.startsWith(QLatin1String("de")))
+ return { QStringLiteral("SPRACHE WÄHLEN"), QStringLiteral("Weiter"), QStringLiteral("INSTALLATION") };
+ return { QStringLiteral("CHOOSE YOUR LANGUAGE"), QStringLiteral("Next"), QStringLiteral("INSTALLER") };
+}
+
+QString fullLocaleName(const QString& localeId)
+{
+ QString lang = QLocale(localeId).name();
+ if (lang.isEmpty())
+ lang = localeId;
+ return lang.contains('.') ? lang : lang + ".UTF-8";
+}
+
+QString nativeName(const QString& localeId)
+{
+ QString name = QLocale(localeId).nativeLanguageName();
+ if (name.isEmpty())
+ return localeId;
+ name[0] = name[0].toUpper();
+ return name;
+}
+}
+
class BgWidget : public QWidget
{
public:
@@ -30,9 +69,16 @@ public:
protected:
void paintEvent(QPaintEvent*) override
{
- if (m_pixmap.isNull()) return;
QPainter p(this);
- p.drawPixmap(rect(), m_pixmap);
+ p.fillRect(rect(), QColor(0x1a, 0x1b, 0x1d));
+ if (m_pixmap.isNull()) return;
+ const QSize scaled = m_pixmap.size().scaled(size(), Qt::KeepAspectRatioByExpanding);
+ const QRect target((width() - scaled.width()) / 2,
+ (height() - scaled.height()) * 4 / 10,
+ scaled.width(),
+ scaled.height());
+ p.setRenderHint(QPainter::SmoothPixmapTransform);
+ p.drawPixmap(target, m_pixmap);
}
private:
@@ -42,7 +88,8 @@ private:
RaveWelcomeViewStep::RaveWelcomeViewStep(QObject* parent)
: Calamares::ViewStep(parent)
{
- m_localeIds = { "de", "en", "en_GB", "hu" };
+ RaveBillentyuzet::regisztral();
+ m_localeIds = { "hu", "en", "en_GB", "de" };
}
RaveWelcomeViewStep::~RaveWelcomeViewStep()
@@ -56,13 +103,13 @@ QString RaveWelcomeViewStep::prettyName() const
const QString locale = getLocale();
if (locale.startsWith("hu"))
{
- return QStringLiteral("Üdvözlés");
+ return QStringLiteral("Nyelv");
}
if (locale.startsWith("de"))
{
- return QStringLiteral("Willkommen");
+ return QStringLiteral("Sprache");
}
- return tr("Welcome");
+ return tr("Language");
}
QString RaveWelcomeViewStep::getLocale() const
@@ -103,53 +150,114 @@ void RaveWelcomeViewStep::buildWidget()
if (!imgPath.isEmpty())
bg->setPixmap(QPixmap(imgPath));
- auto* bar = new QFrame();
- bar->setObjectName("ravewelcomeBar");
- bar->setFixedHeight(58);
+ m_tag = new QLabel();
+ m_tag->setObjectName("ravewelcomeTag");
- m_langCombo = new QComboBox(bar);
- m_langCombo->setObjectName("ravewelcomeCombo");
- m_langCombo->setFixedHeight(40);
- m_langCombo->setMinimumWidth(300);
+ auto* panel = new QFrame();
+ panel->setObjectName("ravewelcomeBar");
- auto* model = new Calamares::Locale::TranslationsModel(m_localeIds, m_langCombo);
- m_langCombo->setModel(model);
+ m_title = new QLabel();
+ m_title->setObjectName("ravewelcomeTitle");
+ m_localeLabel = new QLabel();
+ m_localeLabel->setObjectName("ravewelcomeLocale");
- QLocale sys = QLocale::system();
- QString sysName = sys.name();
- m_currentLocaleIndex = 0;
+ auto* headerLayout = new QHBoxLayout();
+ headerLayout->setContentsMargins(0, 0, 0, 0);
+ headerLayout->addWidget(m_title);
+ headerLayout->addStretch();
+ headerLayout->addWidget(m_localeLabel, 0, Qt::AlignBottom);
+
+ m_langButtons = new QButtonGroup(panel);
+ m_langButtons->setExclusive(true);
+ auto* langLayout = new QGridLayout();
+ langLayout->setContentsMargins(0, 0, 0, 0);
+ langLayout->setHorizontalSpacing(8);
for (int i = 0; i < m_localeIds.size(); ++i)
{
- if (m_localeIds[i] == sysName || sysName.startsWith(m_localeIds[i].left(2)))
- {
- m_currentLocaleIndex = i;
- break;
- }
+ auto* button = new QPushButton(nativeName(m_localeIds[i]));
+ button->setObjectName("ravewelcomeLang");
+ button->setCheckable(true);
+ button->setMinimumHeight(48);
+ button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ m_langButtons->addButton(button, i);
+ langLayout->addWidget(button, 0, i);
+ }
+
+ m_next = new QPushButton();
+ m_next->setObjectName("ravewelcomeNext");
+ m_next->setMinimumHeight(48);
+ connect(m_next, &QPushButton::clicked, this, []()
+ {
+ if (auto* vm = Calamares::ViewManager::instance())
+ vm->next();
+ });
+
+ auto* actionLayout = new QHBoxLayout();
+ actionLayout->setContentsMargins(0, 0, 0, 0);
+ actionLayout->setSpacing(12);
+ actionLayout->addLayout(langLayout, 1);
+ actionLayout->addWidget(m_next);
+
+ auto* panelLayout = new QVBoxLayout(panel);
+ panelLayout->setContentsMargins(24, 20, 24, 20);
+ panelLayout->setSpacing(14);
+ panelLayout->addLayout(headerLayout);
+ panelLayout->addLayout(actionLayout);
+
+ const QString sysName = QLocale::system().name();
+ int exact = -1;
+ int prefix = -1;
+ for (int i = 0; i < m_localeIds.size(); ++i)
+ {
+ if (m_localeIds[i] == sysName)
+ exact = i;
+ else if (prefix < 0 && sysName.startsWith(m_localeIds[i].left(2)))
+ prefix = i;
}
- int enIdx = m_localeIds.indexOf("en");
- if (enIdx >= 0 && m_currentLocaleIndex == 0 && m_localeIds[0] != "en")
- m_currentLocaleIndex = enIdx;
+ if (exact >= 0)
+ m_currentLocaleIndex = exact;
+ else if (prefix >= 0)
+ m_currentLocaleIndex = prefix;
+ else
+ m_currentLocaleIndex = qMax(0, m_localeIds.indexOf("en"));
- m_langCombo->setCurrentIndex(m_currentLocaleIndex);
+ if (auto* button = m_langButtons->button(m_currentLocaleIndex))
+ button->setChecked(true);
applyLiveKeyboardLayout(m_localeIds.value(m_currentLocaleIndex));
- connect(m_langCombo, QOverload<int>::of(&QComboBox::activated),
+ connect(m_langButtons, &QButtonGroup::idClicked,
this, &RaveWelcomeViewStep::onLanguageChanged);
- auto* barLayout = new QHBoxLayout(bar);
- barLayout->setContentsMargins(16, 0, 16, 0);
- barLayout->addStretch();
- barLayout->addWidget(m_langCombo);
- barLayout->addStretch();
-
auto* mainLayout = new QVBoxLayout(bg);
- mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(0);
+ mainLayout->addWidget(m_tag, 0, Qt::AlignLeft | Qt::AlignTop);
mainLayout->addStretch();
- mainLayout->addWidget(bar);
+ mainLayout->addWidget(panel);
m_widget = bg;
+ updateTexts();
+}
+
+void RaveWelcomeViewStep::updateTexts()
+{
+ const QString localeId = m_localeIds.value(m_currentLocaleIndex);
+ const LanguageTexts texts = textsFor(localeId);
+
+ QString version;
+ if (Calamares::Branding::instance())
+ version = Calamares::Branding::instance()->string(Calamares::Branding::Version);
+ const QString product = version.isEmpty() ? QStringLiteral("RAVEOS") : QStringLiteral("RAVEOS ") + version;
+
+ m_tag->setText(product + QStringLiteral(" · ") + texts.installer);
+ m_title->setText(texts.title);
+ m_localeLabel->setText(fullLocaleName(localeId));
+ m_next->setText(texts.next);
+}
+
+QSize RaveWelcomeViewStep::widgetMargins(Qt::Orientations)
+{
+ return QSize(28, 24);
}
QWidget* RaveWelcomeViewStep::widget()
@@ -172,10 +280,10 @@ void RaveWelcomeViewStep::onLanguageChanged(int index)
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
if (gs)
{
- QString lang = QLocale(localeId).name(); // e.g. "hu" -> "hu_HU"
+ QString lang = QLocale(localeId).name();
if (lang.isEmpty())
lang = localeId;
- QString fullLocale = lang.contains('.') ? lang : lang + ".UTF-8";
+ const QString fullLocale = fullLocaleName(localeId);
const char* lcKeys[] = {
"LANG", "LC_NUMERIC", "LC_TIME", "LC_MONETARY", "LC_PAPER",
@@ -195,6 +303,7 @@ void RaveWelcomeViewStep::onLanguageChanged(int index)
Calamares::installTranslator(tid, brandingTranslationsPrefix());
applyLiveKeyboardLayout(localeId);
+ updateTexts();
}
QString RaveWelcomeViewStep::brandingTranslationsPrefix() const
diff --git a/raveos-calamares-module/welcome/RaveWelcomeViewStep.h b/raveos-calamares-module/welcome/RaveWelcomeViewStep.h
index 87b42dd..10289e9 100644
--- a/raveos-calamares-module/welcome/RaveWelcomeViewStep.h
+++ b/raveos-calamares-module/welcome/RaveWelcomeViewStep.h
@@ -8,8 +8,9 @@
#include <viewpages/ViewStep.h>
#include <Job.h>
-class QComboBox;
+class QButtonGroup;
class QLabel;
+class QPushButton;
class PLUGINDLLEXPORT RaveWelcomeViewStep : public Calamares::ViewStep
{
@@ -21,6 +22,7 @@ public:
QString prettyName() const override;
QWidget* widget() override;
+ QSize widgetMargins(Qt::Orientations panelSides) override;
bool isNextEnabled() const override;
bool isBackEnabled() const override;
@@ -36,13 +38,17 @@ private slots:
private:
void buildWidget();
+ void updateTexts();
QString getLocale() const;
QString brandingTranslationsPrefix() const;
void applyLiveKeyboardLayout(const QString& localeId);
- QWidget* m_widget = nullptr;
- QLabel* m_bgLabel = nullptr;
- QComboBox* m_langCombo = nullptr;
+ QWidget* m_widget = nullptr;
+ QButtonGroup* m_langButtons = nullptr;
+ QLabel* m_tag = nullptr;
+ QLabel* m_title = nullptr;
+ QLabel* m_localeLabel = nullptr;
+ QPushButton* m_next = nullptr;
QStringList m_localeIds;
int m_currentLocaleIndex = 0;
diff --git a/raveos-calamares-module/welcome/ravewelcome.conf b/raveos-calamares-module/welcome/ravewelcome.conf
deleted file mode 100644
index 6acb1c7..0000000
--- a/raveos-calamares-module/welcome/ravewelcome.conf
+++ /dev/null
@@ -1,7 +0,0 @@
----
-# Available languages (must match the branding/lang directory)
-languages:
- - de
- - en
- - en_GB
- - hu
diff --git a/raveos-calamares-module/wifi/CMakeLists.txt b/raveos-calamares-module/wifi/CMakeLists.txt
index 28335b2..eb9771f 100644
--- a/raveos-calamares-module/wifi/CMakeLists.txt
+++ b/raveos-calamares-module/wifi/CMakeLists.txt
@@ -23,7 +23,6 @@ install(
install(
FILES
ui/wifi.qml
- ui/Style.qml
ui/Translations.qml
ui/qmldir
DESTINATION lib/calamares/modules/wifi/ui
diff --git a/raveos-calamares-module/wifi/NetworkManager.cpp b/raveos-calamares-module/wifi/NetworkManager.cpp
index cb88698..94abe2b 100644
--- a/raveos-calamares-module/wifi/NetworkManager.cpp
+++ b/raveos-calamares-module/wifi/NetworkManager.cpp
@@ -1,5 +1,7 @@
#include "NetworkManager.h"
+#include <algorithm>
+
#include <QDBusInterface>
#include <QDBusReply>
#include <QDBusObjectPath>
@@ -17,6 +19,13 @@ typedef QMap<QString, QVariantMap> NMConnectionSettings;
static const QString LOG_FILE = "/tmp/calamares-wifi.log";
+static constexpr uint NmDeviceTypeWifi = 2;
+static constexpr uint NmApFlagPrivacy = 0x1;
+static constexpr uint NmKeyMgmtPsk = 0x100;
+static constexpr uint NmKeyMgmt8021x = 0x200;
+static constexpr uint NmKeyMgmtSae = 0x400;
+static constexpr int NmPmfRequired = 3;
+
static void wifiLog(const QString& message)
{
QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
@@ -55,11 +64,6 @@ NetworkManager::NetworkManager(QObject* parent)
timer->start(3000);
}
-QStringList NetworkManager::networks() const
-{
- return m_networks;
-}
-
bool NetworkManager::isConnected() const
{
return m_connected;
@@ -142,7 +146,6 @@ void NetworkManager::updateConnectionState()
void NetworkManager::scan()
{
- m_networks.clear();
wifiLog("Starting scan...");
QDBusInterface nm(
@@ -189,7 +192,7 @@ void NetworkManager::scan()
uint deviceType = typeReply.isValid() ? typeReply.value().toUInt() : 0;
wifiLog(QString("Device %1 type: %2").arg(dev.path()).arg(deviceType));
- if (deviceType != 2) // Not WiFi
+ if (deviceType != NmDeviceTypeWifi)
continue;
foundWireless = true;
@@ -219,7 +222,6 @@ void NetworkManager::scan()
void NetworkManager::fetchAccessPoints()
{
- m_networks.clear();
wifiLog("Fetching access points...");
QDBusInterface nm(
@@ -232,6 +234,7 @@ void NetworkManager::fetchAccessPoints()
if (!nm.isValid())
{
wifiLog("NM interface not valid in fetchAccessPoints");
+ m_accessPoints.clear();
emit networksChanged();
return;
}
@@ -241,10 +244,13 @@ void NetworkManager::fetchAccessPoints()
if (!devices.isValid())
{
wifiLog("GetDevices failed in fetchAccessPoints");
+ m_accessPoints.clear();
emit networksChanged();
return;
}
+ QMap<QString, QVariantMap> strongest;
+
for (const auto& dev : devices.value())
{
QDBusInterface devProps(
@@ -260,8 +266,8 @@ void NetworkManager::fetchAccessPoints()
"DeviceType"
);
- if (!typeReply.isValid() || typeReply.value().toUInt() != 2)
- continue; // Not WiFi
+ if (!typeReply.isValid() || typeReply.value().toUInt() != NmDeviceTypeWifi)
+ continue;
QDBusInterface wirelessIf(
"org.freedesktop.NetworkManager",
@@ -289,22 +295,41 @@ void NetworkManager::fetchAccessPoints()
QDBusConnection::systemBus()
);
- QByteArray ssidRaw = apIf.property("Ssid").toByteArray();
- QString ssid = QString::fromUtf8(ssidRaw);
+ const QString ssid = QString::fromUtf8(apIf.property("Ssid").toByteArray());
+ if (ssid.isEmpty())
+ continue;
- uint frequency = apIf.property("Frequency").toUInt();
- QString band = (frequency > 4000) ? "5GHz" : "2.4GHz";
+ const uint frequency = apIf.property("Frequency").toUInt();
+ const int strength = apIf.property("Strength").toInt();
+ const bool secured = (apIf.property("Flags").toUInt() & NmApFlagPrivacy) != 0
+ || apIf.property("WpaFlags").toUInt() != 0
+ || apIf.property("RsnFlags").toUInt() != 0;
- wifiLog(QString("Found SSID: %1 (%2, %3 MHz)").arg(ssid, band).arg(frequency));
+ wifiLog(QString("Found SSID: %1 (%2 MHz, %3%)").arg(ssid).arg(frequency).arg(strength));
- if (!ssid.isEmpty() && !m_networks.contains(ssid))
- m_networks << ssid;
+ if (strongest.contains(ssid) && strongest[ssid].value("strength").toInt() >= strength)
+ continue;
+
+ QVariantMap item;
+ item.insert("ssid", ssid);
+ item.insert("strength", strength);
+ item.insert("secured", secured);
+ item.insert("band", frequency > 5900 ? QStringLiteral("6 GHz") : frequency > 4000 ? QStringLiteral("5 GHz") : QStringLiteral("2.4 GHz"));
+ strongest.insert(ssid, item);
}
}
- m_networks.sort(Qt::CaseInsensitive);
+ QList<QVariantMap> sorted = strongest.values();
+ std::sort(sorted.begin(), sorted.end(), [](const QVariantMap& a, const QVariantMap& b)
+ {
+ return a.value("strength").toInt() > b.value("strength").toInt();
+ });
+
+ m_accessPoints.clear();
+ for (const auto& item : sorted)
+ m_accessPoints << item;
- wifiLog(QString("Total networks found: %1").arg(m_networks.size()));
+ wifiLog(QString("Total networks found: %1").arg(m_accessPoints.size()));
emit networksChanged();
}
@@ -402,12 +427,12 @@ void NetworkManager::connectTo(const QString& ssid, const QString& password)
}
- bool apSupportsPsk = ((apWpaFlags & 0x100) != 0) || ((apRsnFlags & 0x100) != 0);
- bool apSupportsSae = (apRsnFlags & 0x400) != 0; // WPA3
- bool apSupportsEnterprise = ((apWpaFlags & 0x200) != 0) || ((apRsnFlags & 0x200) != 0);
+ bool apSupportsPsk = ((apWpaFlags & NmKeyMgmtPsk) != 0) || ((apRsnFlags & NmKeyMgmtPsk) != 0);
+ bool apSupportsSae = (apRsnFlags & NmKeyMgmtSae) != 0;
+ bool apSupportsEnterprise = ((apWpaFlags & NmKeyMgmt8021x) != 0) || ((apRsnFlags & NmKeyMgmt8021x) != 0);
bool apIsOpen = (apFlags == 0) && (apWpaFlags == 0) && (apRsnFlags == 0);
- bool apHasPrivacy = (apFlags & 0x1) != 0;
+ bool apHasPrivacy = (apFlags & NmApFlagPrivacy) != 0;
wifiLog(QString("Security detection: PSK=%1, SAE=%2, Enterprise=%3, Open=%4, Privacy=%5")
.arg(apSupportsPsk).arg(apSupportsSae).arg(apSupportsEnterprise).arg(apIsOpen).arg(apHasPrivacy));
@@ -448,23 +473,13 @@ void NetworkManager::connectTo(const QString& ssid, const QString& password)
wifiLog("Using WPA3-SAE security");
wifiSecurity["key-mgmt"] = QString("sae");
wifiSecurity["psk"] = password;
- wifiSecurity["pmf"] = 3;
+ wifiSecurity["pmf"] = NmPmfRequired;
}
else if (apSupportsPsk)
{
- if (apSupportsSae)
- {
- wifiLog("Using WPA3-SAE (transition mode - both PSK and SAE available)");
- wifiSecurity["key-mgmt"] = QString("sae");
- wifiSecurity["psk"] = password;
- wifiSecurity["pmf"] = 3; // Required for SAE
- }
- else
- {
- wifiLog("Using WPA-PSK security");
- wifiSecurity["key-mgmt"] = QString("wpa-psk");
- wifiSecurity["psk"] = password;
- }
+ wifiLog("Using WPA-PSK security");
+ wifiSecurity["key-mgmt"] = QString("wpa-psk");
+ wifiSecurity["psk"] = password;
}
else if (isHiddenNetwork)
{
@@ -540,17 +555,13 @@ void NetworkManager::connectTo(const QString& ssid, const QString& password)
{
m_lastSecurityType = "sae";
}
- else if (apSupportsPsk && apSupportsSae)
- {
- m_lastSecurityType = "sae"; // Transition mode, we used SAE
- }
else if (apSupportsPsk)
{
m_lastSecurityType = "wpa-psk";
}
else
{
- m_lastSecurityType = ""; // Open network
+ m_lastSecurityType = "";
}
wifiLog(QString("Stored security type: '%1'").arg(m_lastSecurityType));
diff --git a/raveos-calamares-module/wifi/NetworkManager.h b/raveos-calamares-module/wifi/NetworkManager.h
index dd58a9a..9f74bcb 100644
--- a/raveos-calamares-module/wifi/NetworkManager.h
+++ b/raveos-calamares-module/wifi/NetworkManager.h
@@ -3,22 +3,23 @@
#include <QObject>
#include <QString>
#include <QStringList>
+#include <QVariantList>
class NetworkManager : public QObject
{
Q_OBJECT
- Q_PROPERTY(QStringList networks READ networks NOTIFY networksChanged)
+ Q_PROPERTY(QVariantList accessPoints READ accessPoints NOTIFY networksChanged)
Q_PROPERTY(bool connected READ isConnected NOTIFY connectionChanged)
public:
explicit NetworkManager(QObject* parent = nullptr);
- QStringList networks() const;
+ QVariantList accessPoints() const { return m_accessPoints; }
bool isConnected() const;
QString lastConnectedSsid() const { return m_lastConnectedSsid; }
QString lastConnectedPassword() const { return m_lastConnectedPassword; }
- QString lastSecurityType() const { return m_lastSecurityType; } // "wpa-psk" or "sae"
+ QString lastSecurityType() const { return m_lastSecurityType; }
public slots:
void scan();
@@ -36,11 +37,11 @@ private:
void updateConnectionState();
void fetchAccessPoints();
- QStringList m_networks;
+ QVariantList m_accessPoints;
bool m_connected = false;
QString m_lastConnectedSsid;
QString m_lastConnectedPassword;
- QString m_lastSecurityType; // "wpa-psk", "sae", or "" (open)
+ QString m_lastSecurityType;
int m_connectionCheckCount = 0;
};
diff --git a/raveos-calamares-module/wifi/WifiViewStep.cpp b/raveos-calamares-module/wifi/WifiViewStep.cpp
index 350bd43..7f0e7dc 100644
--- a/raveos-calamares-module/wifi/WifiViewStep.cpp
+++ b/raveos-calamares-module/wifi/WifiViewStep.cpp
@@ -1,5 +1,7 @@
#include "WifiViewStep.h"
+#include "../common/RaveBrandingQml.h"
+
#include <QVBoxLayout>
#include <QQuickWidget>
#include <QQmlContext>
@@ -50,15 +52,24 @@ WifiViewStep::~WifiViewStep()
QString WifiViewStep::prettyName() const
{
- m_locale = getLocale();
-
- if (m_locale.startsWith("hu"))
- {
- return QStringLiteral("Wi-Fi");
- }
return QStringLiteral("Wi-Fi");
}
+QString WifiViewStep::prettyStatus() const
+{
+ const QString ssid = m_networkManager && m_networkManager->isConnected() ? m_networkManager->lastConnectedSsid() : QString();
+ if (!ssid.isEmpty())
+ return QStringLiteral("Wi-Fi: <b>%1</b>").arg(ssid.toHtmlEscaped());
+ if (!hasActiveNetwork())
+ return QString();
+ const QString locale = getLocale();
+ if (locale.startsWith("hu"))
+ return QStringLiteral("Meglévő hálózati kapcsolat");
+ if (locale.startsWith("de"))
+ return QStringLiteral("Bestehende Netzwerkverbindung");
+ return QStringLiteral("Existing network connection");
+}
+
QWidget* WifiViewStep::widget()
{
if (!m_widget)
@@ -88,6 +99,7 @@ QWidget* WifiViewStep::widget()
qmlPath = QDir::currentPath() + QStringLiteral("/wifi/ui/wifi.qml");
}
+ addRaveBrandingImportPath(m_quickWidget->engine());
m_quickWidget->setSource(QUrl::fromLocalFile(qmlPath));
layout->addWidget(m_quickWidget);
diff --git a/raveos-calamares-module/wifi/WifiViewStep.h b/raveos-calamares-module/wifi/WifiViewStep.h
index efe3e64..b03102a 100644
--- a/raveos-calamares-module/wifi/WifiViewStep.h
+++ b/raveos-calamares-module/wifi/WifiViewStep.h
@@ -21,6 +21,7 @@ public:
~WifiViewStep() override;
QString prettyName() const override;
+ QString prettyStatus() const override;
QWidget* widget() override;
bool isNextEnabled() const override;
diff --git a/raveos-calamares-module/wifi/ui/Style.qml b/raveos-calamares-module/wifi/ui/Style.qml
deleted file mode 100644
index 360d4d2..0000000
--- a/raveos-calamares-module/wifi/ui/Style.qml
+++ /dev/null
@@ -1,161 +0,0 @@
-pragma Singleton
-import QtQuick 2.15
-
-/**
- * WiFi Modul Stílus Beállítások
- * ==============================
- *
- * Itt tudod testreszabni a modul kinézetét.
- * Minden szín hexadecimális formátumban van megadva: #RRGGBB
- *
- * Példa színek:
- * Fehér: #ffffff
- * Fekete: #000000
- * Piros: #ff0000
- * Zöld: #00ff00
- * Kék: #0000ff
- */
-
-QtObject {
- // =========================================
- // HÁTTÉR SZÍNEK
- // =========================================
-
- // Fő háttérszín (az egész modul háttere)
- readonly property color backgroundColor: "#404040"
-
- // Lista háttérszín (ahol a WiFi hálózatok vannak)
- readonly property color listBackgroundColor: "#2B2B2B"
-
- // Lista fejléc háttérszín ("Elérhető hálózatok" sor)
- readonly property color listHeaderColor: "#3d7839"
-
- // Elem hover háttérszín (amikor az egér fölötte van)
- readonly property color itemHoverColor: "#2d3238"
-
- // Kiválasztott elem háttérszín
- readonly property color itemSelectedColor: "#3d7839"
-
- // =========================================
- // SZÖVEG SZÍNEK
- // =========================================
-
- // Fő szöveg szín (címek, hálózat nevek)
- readonly property color textColor: "#ffffff"
-
- // Másodlagos szöveg szín (leírások, információk)
- readonly property color textSecondaryColor: "#b2b2b2"
-
- // Halványított szöveg szín (tippek, kihagyható info)
- readonly property color textMutedColor: "#707070"
-
- // Letiltott szöveg szín
- readonly property color textDisabledColor: "#606060"
-
- // =========================================
- // GOMB SZÍNEK
- // =========================================
-
- // Fő gomb háttérszín (Csatlakozás gomb)
- readonly property color buttonPrimaryColor: "#3d7839"
-
- // Fő gomb hover szín
- readonly property color buttonPrimaryHoverColor: "#3d7839"
-
- // Másodlagos gomb háttérszín (Frissítés gomb)
- readonly property color buttonSecondaryColor: "#3d4248"
-
- // Másodlagos gomb hover szín
- readonly property color buttonSecondaryHoverColor: "#4a5058"
-
- // Letiltott gomb háttérszín
- readonly property color buttonDisabledColor: "#3d4248"
-
- // =========================================
- // INPUT MEZŐ SZÍNEK
- // =========================================
-
- // Input mező háttérszín
- readonly property color inputBackgroundColor: "#2B2B2B"
-
- // Input mező letiltott háttérszín
- readonly property color inputDisabledColor: "#2B2B2B"
-
- // Input mező placeholder szöveg szín
- readonly property color inputPlaceholderColor: "#FFFFFF"
-
- // Input mező keret szín
- readonly property color inputBorderColor: "#3d4248"
-
- // Input mező fókuszált keret szín
- readonly property color inputFocusBorderColor: "#3d7839"
-
- // =========================================
- // ÁLLAPOT SZÍNEK
- // =========================================
-
- // Sikeres állapot szín (csatlakozva)
- readonly property color successColor: "#2e7d32"
-
- // Sikeres pipa szín
- readonly property color successCheckColor: "#4CAF50"
-
- // Folyamatban állapot szín (csatlakozás...)
- readonly property color progressColor: "#37474f"
-
- // Toggle bekapcsolt szín
- readonly property color toggleOnColor: "#4CAF50"
-
- // Toggle kikapcsolt szín
- readonly property color toggleOffColor: "#555555"
-
- // =========================================
- // KERET ÉS VONAL SZÍNEK
- // =========================================
-
- // Lista keret szín
- readonly property color borderColor: "#3d4248"
-
- // Elválasztó vonal szín (lista elemek között)
- readonly property color separatorColor: "#3d4248"
-
- // =========================================
- // MÉRETEK
- // =========================================
-
- // Címsor betűméret
- readonly property int fontSizeTitle: 24
-
- // Alcím betűméret
- readonly property int fontSizeSubtitle: 12
-
- // Normál szöveg betűméret
- readonly property int fontSizeNormal: 14
-
- // Kis szöveg betűméret
- readonly property int fontSizeSmall: 12
-
- // Apró szöveg betűméret
- readonly property int fontSizeTiny: 11
-
- // Lista elem magasság
- readonly property int listItemHeight: 48
-
- // Gomb magasság
- readonly property int buttonHeight: 48
-
- // Input mező magasság
- readonly property int inputHeight: 44
-
- // Kerekítés sugara
- readonly property int borderRadius: 6
-
- // Nagy kerekítés sugara (lista)
- readonly property int borderRadiusLarge: 8
-
- // Belső margó
- readonly property int spacing: 16
-
- // Külső margó
- readonly property int margin: 20
-} \ No newline at end of file
diff --git a/raveos-calamares-module/wifi/ui/Translations.qml b/raveos-calamares-module/wifi/ui/Translations.qml
index 21ef6df..601e8eb 100644
--- a/raveos-calamares-module/wifi/ui/Translations.qml
+++ b/raveos-calamares-module/wifi/ui/Translations.qml
@@ -1,183 +1,88 @@
pragma Singleton
import QtQuick 2.15
-/**
- * WiFi Modul Fordítások
- * ======================
- *
- * Támogatott nyelvek:
- * - hu_HU: Magyar
- * - de_DE: Német
- * - en_US, en_GB, stb.: Angol (alapértelmezett)
- *
- * Új nyelv hozzáadása:
- * 1. Adj hozzá egy új "else if" blokkot a setLanguage függvényben
- * 2. Másold be az összes szöveget és fordítsd le
- *
- * Használat QML-ben:
- * Text { text: Translations.title }
- */
-
QtObject {
- id: root
-
- // Aktuális nyelv kód (pl. "hu_HU", "en_US")
- property string currentLanguage: "en_US"
-
- // =========================================
- // CÍMEK ÉS FEJLÉCEK
- // =========================================
-
- // Sidebar név (bal oldali menüben)
- property string sidebarName: "Hálózat"
-
- // Modul fő címe
- property string title: "Wi-Fi Network"
-
- // Alcím / leírás
- property string subtitle: "Select a network from the list, or enter a hidden network name manually."
-
- // Lista fejléc
+ property string eyebrow: "WI-FI"
+ property string title: "CONNECT TO A NETWORK"
+ property string subtitle: "The installer downloads the latest packages from the internet. With a cable connection this step is skipped automatically."
property string availableNetworks: "Available networks"
-
- // =========================================
- // GOMBOK
- // =========================================
-
- // Frissítés gomb
property string refresh: "Refresh"
-
- // Csatlakozás gomb
+ property string noNetworks: "No networks found. Click Refresh to search again."
+ property string selected: "Selected"
+ property string noSelection: "Select a network from the list"
+ property string password: "Password"
property string connect: "Connect"
-
- // =========================================
- // INPUT MEZŐK
- // =========================================
-
- // SSID mező placeholder
- property string ssidPlaceholder: "Network name (SSID)"
-
- // Jelszó mező placeholder
- property string passwordPlaceholder: "Password"
-
- // Jelszó megjelenítő/elrejtő gomb
- property string showPassword: "Show"
- property string hidePassword: "Hide"
-
- // =========================================
- // ÁLLAPOT ÜZENETEK
- // =========================================
-
- // Sikeres csatlakozás
- property string connected: "Successfully connected!"
-
- // Csatlakozás folyamatban
- property string connecting: "Connecting..."
-
- // Nincs hálózat
- property string noNetworks: "No networks found.\nClick Refresh to scan."
-
- // =========================================
- // TOGGLE ÉS OPCIÓK
- // =========================================
-
- // Rejtett hálózat toggle
property string hiddenNetwork: "Hidden network"
+ property string ssidLabel: "Network name (SSID)"
+ property string statusLabel: "Status"
+ property string statusDisconnected: "not connected"
+ property string statusConnecting: "connecting..."
+ property string statusConnected: "connected"
+ property string statusFailed: "connection failed"
+ property string secured: "Password protected"
+ property string showPassword: "Show password"
- // =========================================
- // INFORMÁCIÓS SZÖVEGEK
- // =========================================
-
- // Sikeres csatlakozás után
- property string clickNextToContinue: "Click Next to continue."
-
- // Ha van vezetékes kapcsolat
- property string canSkipWithEthernet: "If you have a wired connection, you can skip this step."
-
- // =========================================
- // NYELV BEÁLLÍTÁS FÜGGVÉNY
- // =========================================
-
- /**
- * Nyelv beállítása a locale kód alapján
- * @param locale - Nyelv kód (pl. "hu_HU", "en_US")
- */
function setLanguage(locale) {
- currentLanguage = locale
-
- // ==================
- // MAGYAR
- // ==================
if (locale.startsWith("hu")) {
- sidebarName = "Hálózat"
- title = "Wi-Fi hálózat"
- subtitle = "Válassz egy hálózatot a listából, vagy add meg kézzel a rejtett hálózat nevét."
+ eyebrow = "WI-FI"
+ title = "CSATLAKOZÁS A HÁLÓZATHOZ"
+ subtitle = "A telepítő az internetről tölti le a legfrissebb csomagokat. Kábellel csatlakozva ez a lépés magától kimarad."
availableNetworks = "Elérhető hálózatok"
refresh = "Frissítés"
+ noNetworks = "Nem található hálózat. Kattints a Frissítésre az újbóli kereséshez."
+ selected = "Kiválasztva"
+ noSelection = "Válassz egy hálózatot a listából"
+ password = "Jelszó"
connect = "Csatlakozás"
- ssidPlaceholder = "Hálózat neve (SSID)"
- passwordPlaceholder = "Jelszó"
- showPassword = "Mutat"
- hidePassword = "Elrejt"
- connected = "Sikeresen csatlakozva!"
- connecting = "Csatlakozás..."
- noNetworks = "Nem található hálózat.\nKattints a Frissítés gombra."
hiddenNetwork = "Rejtett hálózat"
- clickNextToContinue = "Kattints a Tovább gombra a folytatáshoz."
- canSkipWithEthernet = "Ha van vezetékes kapcsolatod, kihagyhatod ezt a lépést."
- }
- // ==================
- // NÉMET
- // ==================
- else if (locale.startsWith("de")) {
- sidebarName = "Netzwerk"
- title = "WLAN-Netzwerk"
- subtitle = "Wählen Sie ein Netzwerk aus der Liste oder geben Sie den Namen eines versteckten Netzwerks manuell ein."
+ ssidLabel = "Hálózat neve (SSID)"
+ statusLabel = "Állapot"
+ statusDisconnected = "nincs kapcsolat"
+ statusConnecting = "csatlakozás..."
+ statusConnected = "csatlakozva"
+ statusFailed = "a csatlakozás nem sikerült"
+ secured = "Jelszóval védett"
+ showPassword = "Jelszó megjelenítése"
+ } else if (locale.startsWith("de")) {
+ eyebrow = "WLAN"
+ title = "MIT EINEM NETZWERK VERBINDEN"
+ subtitle = "Der Installer lädt die neuesten Pakete aus dem Internet. Mit Kabelverbindung wird dieser Schritt automatisch übersprungen."
availableNetworks = "Verfügbare Netzwerke"
refresh = "Aktualisieren"
+ noNetworks = "Keine Netzwerke gefunden. Klicke auf Aktualisieren, um erneut zu suchen."
+ selected = "Ausgewählt"
+ noSelection = "Wähle ein Netzwerk aus der Liste"
+ password = "Passwort"
connect = "Verbinden"
- ssidPlaceholder = "Netzwerkname (SSID)"
- passwordPlaceholder = "Passwort"
- showPassword = "Anzeigen"
- hidePassword = "Ausblenden"
- connected = "Erfolgreich verbunden!"
- connecting = "Verbinden..."
- noNetworks = "Keine Netzwerke gefunden.\nZum Scannen auf Aktualisieren klicken."
hiddenNetwork = "Verstecktes Netzwerk"
- clickNextToContinue = "Klicken Sie auf Weiter, um fortzufahren."
- canSkipWithEthernet = "Wenn Sie eine Kabelverbindung haben, können Sie diesen Schritt überspringen."
- }
- // ==================
- // ANGOL (alapértelmezett)
- // ==================
- else {
- sidebarName = "Network"
- title = "Wi-Fi Network"
- subtitle = "Select a network from the list, or enter a hidden network name manually."
+ ssidLabel = "Netzwerkname (SSID)"
+ statusLabel = "Status"
+ statusDisconnected = "nicht verbunden"
+ statusConnecting = "verbinde..."
+ statusConnected = "verbunden"
+ statusFailed = "Verbindung fehlgeschlagen"
+ secured = "Passwortgeschützt"
+ showPassword = "Passwort anzeigen"
+ } else {
+ eyebrow = "WI-FI"
+ title = "CONNECT TO A NETWORK"
+ subtitle = "The installer downloads the latest packages from the internet. With a cable connection this step is skipped automatically."
availableNetworks = "Available networks"
refresh = "Refresh"
+ noNetworks = "No networks found. Click Refresh to search again."
+ selected = "Selected"
+ noSelection = "Select a network from the list"
+ password = "Password"
connect = "Connect"
- ssidPlaceholder = "Network name (SSID)"
- passwordPlaceholder = "Password"
- showPassword = "Show"
- hidePassword = "Hide"
- connected = "Successfully connected!"
- connecting = "Connecting..."
- noNetworks = "No networks found.\nClick Refresh to scan."
hiddenNetwork = "Hidden network"
- clickNextToContinue = "Click Next to continue."
- canSkipWithEthernet = "If you have a wired connection, you can skip this step."
+ ssidLabel = "Network name (SSID)"
+ statusLabel = "Status"
+ statusDisconnected = "not connected"
+ statusConnecting = "connecting..."
+ statusConnected = "connected"
+ statusFailed = "connection failed"
+ secured = "Password protected"
+ showPassword = "Show password"
}
-
- // ==================
- // TOVÁBBI NYELVEK IDE
- // ==================
- // Példa német nyelv hozzáadása:
- //
- // else if (locale.startsWith("de")) {
- // title = "WLAN-Netzwerk"
- // subtitle = "Wählen Sie ein Netzwerk aus der Liste..."
- // // ... stb.
- // }
}
}
diff --git a/raveos-calamares-module/wifi/ui/qmldir b/raveos-calamares-module/wifi/ui/qmldir
index e80b555..6f9105d 100644
--- a/raveos-calamares-module/wifi/ui/qmldir
+++ b/raveos-calamares-module/wifi/ui/qmldir
@@ -1,3 +1,2 @@
module WifiModule
-singleton Style 1.0 Style.qml
singleton Translations 1.0 Translations.qml
diff --git a/raveos-calamares-module/wifi/ui/wifi.qml b/raveos-calamares-module/wifi/ui/wifi.qml
index aee3ddc..e3b0b0c 100644
--- a/raveos-calamares-module/wifi/ui/wifi.qml
+++ b/raveos-calamares-module/wifi/ui/wifi.qml
@@ -1,404 +1,405 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
+import RaveOS 1.0
import "." as WifiModule
Rectangle {
id: root
- color: WifiModule.Style.backgroundColor
+ color: Stilus.hatter
- property string selectedSsid: ""
- property bool showHiddenNetwork: false
- property bool isConnecting: false
- property bool showPassword: false
+ readonly property var t: WifiModule.Translations
+ property var kivalasztott: null
+ property bool rejtett: false
+ property bool csatlakozik: false
+ property bool sikertelen: false
+ property bool jelszoLatszik: false
+
+ readonly property string ssid: rejtett ? ssidMezo.text : (kivalasztott ? kivalasztott.ssid : "")
+ readonly property bool jelszoKell: rejtett || (kivalasztott !== null && kivalasztott.secured)
- // Function to update language - called from C++
function updateLanguage() {
WifiModule.Translations.setLanguage(systemLocale)
}
- // Initialize translations on load
- Component.onCompleted: {
- WifiModule.Translations.setLanguage(systemLocale)
+ function savok(erosseg) {
+ if (erosseg >= 75) return 4
+ if (erosseg >= 50) return 3
+ if (erosseg >= 25) return 2
+ return 1
}
- ColumnLayout {
- anchors.fill: parent
- anchors.margins: WifiModule.Style.margin
- spacing: WifiModule.Style.spacing
+ function allapotSzoveg() {
+ if (nm.connected) return t.statusConnected
+ if (csatlakozik) return t.statusConnecting
+ if (sikertelen) return t.statusFailed
+ return t.statusDisconnected
+ }
+
+ Component.onCompleted: WifiModule.Translations.setLanguage(systemLocale)
- // Header
- Label {
- text: WifiModule.Translations.title
- font.pixelSize: WifiModule.Style.fontSizeTitle
- font.bold: true
- color: WifiModule.Style.textColor
- Layout.alignment: Qt.AlignHCenter
+ Connections {
+ target: nm
+ function onConnectionChanged() {
+ if (nm.connected)
+ root.csatlakozik = false
+ }
+ function onConnectionFailed(error) {
+ root.csatlakozik = false
+ root.sikertelen = true
}
+ }
- Label {
- text: WifiModule.Translations.subtitle
- font.pixelSize: WifiModule.Style.fontSizeSubtitle
- color: WifiModule.Style.textSecondaryColor
- wrapMode: Text.WordWrap
- Layout.fillWidth: true
- Layout.alignment: Qt.AlignHCenter
- horizontalAlignment: Text.AlignHCenter
+ Timer {
+ interval: 30000
+ running: root.csatlakozik
+ onTriggered: {
+ if (!nm.connected) {
+ root.csatlakozik = false
+ root.sikertelen = true
+ }
}
+ }
- // Connection status banner
- Rectangle {
- Layout.fillWidth: true
- height: 40
- radius: WifiModule.Style.borderRadius
- color: nm.connected ? WifiModule.Style.successColor : WifiModule.Style.progressColor
- visible: nm.connected || isConnecting
+ component SzovegLink: Text {
+ signal kattint()
+ color: linkHover.hovered ? Stilus.zoldHover : Stilus.zold
+ font.family: Stilus.font
+ font.pixelSize: 13
+ font.weight: Font.DemiBold
- RowLayout {
- anchors.centerIn: parent
- spacing: 10
+ HoverHandler {
+ id: linkHover
+ cursorShape: Qt.PointingHandCursor
+ }
- BusyIndicator {
- running: isConnecting && !nm.connected
- visible: isConnecting && !nm.connected
- Layout.preferredWidth: 24
- Layout.preferredHeight: 24
- }
+ TapHandler {
+ onTapped: parent.kattint()
+ }
+ }
- Label {
- text: nm.connected ? WifiModule.Translations.connected : WifiModule.Translations.connecting
- color: WifiModule.Style.textColor
- font.pixelSize: WifiModule.Style.fontSizeNormal
- font.bold: true
- }
+ ColumnLayout {
+ anchors.fill: parent
+ anchors.topMargin: 40
+ anchors.bottomMargin: 32
+ anchors.leftMargin: 56
+ anchors.rightMargin: 56
+ spacing: 20
+
+ ColumnLayout {
+ Layout.fillWidth: true
+ spacing: 10
+
+ Fejlec {
+ Layout.fillWidth: true
+ felirat: root.t.eyebrow
+ cim: root.t.title
+ }
+
+ Text {
+ Layout.fillWidth: true
+ text: root.t.subtitle
+ wrapMode: Text.WordWrap
+ color: Stilus.szovegMasodlagos
+ font.family: Stilus.font
+ font.pixelSize: 14
}
}
- // Network list
- Rectangle {
+ RowLayout {
Layout.fillWidth: true
Layout.fillHeight: true
- color: WifiModule.Style.listBackgroundColor
- radius: WifiModule.Style.borderRadiusLarge
- border.color: WifiModule.Style.borderColor
- border.width: 1
+ spacing: 24
ColumnLayout {
- anchors.fill: parent
- anchors.margins: 1
- spacing: 0
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ spacing: 8
- // List header with refresh button
- Rectangle {
+ RowLayout {
Layout.fillWidth: true
- height: 44
- color: WifiModule.Style.listHeaderColor
- radius: WifiModule.Style.borderRadiusLarge
- Rectangle {
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- height: 8
- color: parent.color
+ Text {
+ Layout.fillWidth: true
+ text: root.t.availableNetworks
+ color: Stilus.szovegHalvany
+ font.family: Stilus.font
+ font.pixelSize: 12
+ font.weight: Font.Medium
+ font.letterSpacing: 1
+ font.capitalization: Font.AllUppercase
}
- RowLayout {
- anchors.fill: parent
- anchors.leftMargin: 12
- anchors.rightMargin: 8
+ SzovegLink {
+ text: root.t.refresh
+ onKattint: nm.scan()
+ }
+ }
- Label {
- text: WifiModule.Translations.availableNetworks
- color: WifiModule.Style.textColor
- font.pixelSize: WifiModule.Style.fontSizeSmall
- font.bold: true
- }
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ color: Stilus.felulet
+ border.width: 1
+ border.color: Stilus.keret
- Item { Layout.fillWidth: true }
+ ListView {
+ id: lista
+ anchors.fill: parent
+ anchors.margins: 1
+ clip: true
+ model: nm.accessPoints
+ boundsBehavior: Flickable.StopAtBounds
+ ScrollBar.vertical: Gorgeto {}
- Button {
- text: WifiModule.Translations.refresh
- Layout.preferredHeight: 32
- onClicked: nm.scan()
+ delegate: Rectangle {
+ id: sor
+ readonly property bool kijelolt: !root.rejtett && root.kivalasztott !== null && root.kivalasztott.ssid === modelData.ssid
+ width: lista.width
+ height: 48
+ color: kijelolt ? Stilus.aktiv : (sorHover.hovered ? Stilus.aktiv : "transparent")
- background: Rectangle {
- color: parent.hovered ? WifiModule.Style.buttonSecondaryHoverColor : WifiModule.Style.buttonSecondaryColor
- radius: 4
+ Rectangle {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ height: 1
+ color: Stilus.aktiv
}
- contentItem: Label {
- text: parent.text
- color: WifiModule.Style.textColor
- font.pixelSize: WifiModule.Style.fontSizeSmall
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
+ Rectangle {
+ visible: sor.kijelolt
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ width: 2
+ color: Stilus.zold
}
- }
- }
- }
- // WiFi list
- ListView {
- id: networkList
- Layout.fillWidth: true
- Layout.fillHeight: true
- clip: true
- model: nm.networks
+ RowLayout {
+ anchors.fill: parent
+ anchors.leftMargin: 14
+ anchors.rightMargin: 14
+ spacing: 12
- delegate: Rectangle {
- width: networkList.width
- height: WifiModule.Style.listItemHeight
- color: modelData === selectedSsid ? WifiModule.Style.itemSelectedColor :
- (mouseArea.containsMouse ? WifiModule.Style.itemHoverColor : "transparent")
+ Row {
+ Layout.alignment: Qt.AlignVCenter
+ spacing: 2
+ height: 14
- RowLayout {
- anchors.fill: parent
- anchors.leftMargin: 16
- anchors.rightMargin: 16
- spacing: 12
+ Repeater {
+ model: 4
+ Rectangle {
+ anchors.bottom: parent.bottom
+ width: 3
+ height: 4 + index * 3.3
+ color: index < root.savok(modelData.strength)
+ ? (sor.kijelolt ? Stilus.zold : Stilus.szoveg)
+ : Stilus.keretErosebb
+ }
+ }
+ }
- Label {
- text: ""
- font.pixelSize: 18
- }
+ Text {
+ Layout.fillWidth: true
+ text: modelData.ssid
+ elide: Text.ElideRight
+ color: Stilus.szoveg
+ font.family: Stilus.font
+ font.pixelSize: 14
+ font.weight: sor.kijelolt ? Font.DemiBold : Font.Normal
+ }
- Label {
- text: modelData
- color: WifiModule.Style.textColor
- font.pixelSize: WifiModule.Style.fontSizeNormal
- Layout.fillWidth: true
- elide: Text.ElideRight
- }
+ Canvas {
+ visible: modelData.secured
+ Layout.preferredWidth: 14
+ Layout.preferredHeight: 14
+ Accessible.name: root.t.secured
+ onPaint: {
+ var c = getContext("2d")
+ c.reset()
+ c.strokeStyle = Stilus.szovegHalvany
+ c.lineWidth = 1.5
+ c.strokeRect(3, 6.5, 8, 6)
+ c.beginPath()
+ c.moveTo(4.5, 6.5)
+ c.lineTo(4.5, 4.5)
+ c.arc(7, 4.5, 2.5, Math.PI, 0)
+ c.lineTo(9.5, 6.5)
+ c.stroke()
+ }
+ }
- Label {
- text: modelData === selectedSsid ? "✓" : ""
- color: WifiModule.Style.successCheckColor
- font.pixelSize: 16
- font.bold: true
+ Text {
+ Layout.preferredWidth: 52
+ horizontalAlignment: Text.AlignRight
+ text: modelData.band
+ color: Stilus.szovegHalvany
+ font.family: Stilus.mono
+ font.pixelSize: 11
+ }
}
- }
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- hoverEnabled: true
- onClicked: {
- selectedSsid = modelData
- showHiddenNetwork = false
- ssidField.text = modelData
+ HoverHandler { id: sorHover }
+
+ TapHandler {
+ onTapped: {
+ root.rejtett = false
+ root.sikertelen = false
+ root.kivalasztott = modelData
+ jelszoMezo.text = ""
+ }
}
}
- Rectangle {
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.leftMargin: 16
- anchors.rightMargin: 16
- height: 1
- color: WifiModule.Style.separatorColor
+ Text {
+ anchors.centerIn: parent
+ width: parent.width - 40
+ visible: lista.count === 0
+ text: root.t.noNetworks
+ horizontalAlignment: Text.AlignHCenter
+ wrapMode: Text.WordWrap
+ color: Stilus.szovegHalvany
+ font.family: Stilus.font
+ font.pixelSize: 13
}
}
-
- Label {
- anchors.centerIn: parent
- text: WifiModule.Translations.noNetworks
- color: WifiModule.Style.textMutedColor
- font.pixelSize: WifiModule.Style.fontSizeSmall
- horizontalAlignment: Text.AlignHCenter
- visible: nm.networks.length === 0
- }
}
- }
- }
- // Hidden network toggle
- Rectangle {
- Layout.fillWidth: true
- height: WifiModule.Style.inputHeight
- color: "#3d7839"
- radius: WifiModule.Style.borderRadius
-
- MouseArea {
- anchors.fill: parent
- onClicked: {
- showHiddenNetwork = !showHiddenNetwork
- if (showHiddenNetwork) {
- selectedSsid = ""
- ssidField.text = ""
- ssidField.focus = true
+ SzovegLink {
+ text: root.t.hiddenNetwork
+ onKattint: {
+ root.rejtett = true
+ root.kivalasztott = null
+ root.sikertelen = false
}
}
}
- RowLayout {
- anchors.fill: parent
- anchors.leftMargin: 16
- anchors.rightMargin: 16
-
- Label {
- text: WifiModule.Translations.hiddenNetwork
- color: WifiModule.Style.textColor
- font.pixelSize: WifiModule.Style.fontSizeNormal
- }
-
- Item { Layout.fillWidth: true }
+ Rectangle {
+ Layout.preferredWidth: 300
+ Layout.alignment: Qt.AlignTop
+ implicitHeight: panel.implicitHeight + 36
+ color: Stilus.felulet
+ border.width: 1
+ border.color: Stilus.keret
- Rectangle {
- width: 44
- height: 24
- radius: 12
- color: showHiddenNetwork ? WifiModule.Style.toggleOnColor : WifiModule.Style.toggleOffColor
+ ColumnLayout {
+ id: panel
+ x: 18
+ y: 18
+ width: parent.width - 36
+ spacing: 14
- Rectangle {
- width: 20
- height: 20
- radius: 10
- color: WifiModule.Style.textColor
- x: showHiddenNetwork ? 22 : 2
- anchors.verticalCenter: parent.verticalCenter
+ Text {
+ text: root.t.selected
+ color: Stilus.szovegHalvany
+ font.family: Stilus.font
+ font.pixelSize: 12
+ font.letterSpacing: 1
+ font.capitalization: Font.AllUppercase
+ }
- Behavior on x {
- NumberAnimation { duration: 150 }
- }
+ Text {
+ visible: !root.rejtett
+ Layout.fillWidth: true
+ text: root.kivalasztott ? root.kivalasztott.ssid : root.t.noSelection
+ elide: Text.ElideRight
+ color: root.kivalasztott ? Stilus.szoveg : Stilus.szovegHalvany
+ font.family: Stilus.font
+ font.pixelSize: root.kivalasztott ? 16 : 13
+ font.weight: root.kivalasztott ? Font.DemiBold : Font.Normal
}
- }
- }
- }
- // SSID field (for hidden networks)
- TextField {
- id: ssidField
- Layout.fillWidth: true
- placeholderText: WifiModule.Translations.ssidPlaceholder
- visible: showHiddenNetwork
- color: WifiModule.Style.textColor
- placeholderTextColor: WifiModule.Style.inputPlaceholderColor
- font.pixelSize: WifiModule.Style.fontSizeNormal
+ ColumnLayout {
+ visible: root.rejtett
+ Layout.fillWidth: true
+ spacing: 6
- background: Rectangle {
- color: WifiModule.Style.inputBackgroundColor
- radius: WifiModule.Style.borderRadius
- border.color: ssidField.focus ? WifiModule.Style.inputFocusBorderColor : WifiModule.Style.inputBorderColor
- border.width: 1
- }
- }
+ Text {
+ text: root.t.ssidLabel
+ color: Stilus.szovegHalvany
+ font.family: Stilus.font
+ font.pixelSize: 12
+ }
- // Password field with show/hide toggle
- Item {
- Layout.fillWidth: true
- Layout.preferredHeight: WifiModule.Style.inputHeight
+ TextField {
+ id: ssidMezo
+ Layout.fillWidth: true
+ implicitHeight: 44
+ leftPadding: 12
+ color: Stilus.szoveg
+ font.family: Stilus.font
+ font.pixelSize: 14
+ background: Rectangle {
+ color: Stilus.hatter
+ border.width: 1
+ border.color: ssidMezo.activeFocus ? Stilus.zold : Stilus.keretErosebb
+ }
+ }
+ }
- TextField {
- id: passField
- anchors.fill: parent
- rightPadding: showPasswordButton.width + 16
- placeholderText: WifiModule.Translations.passwordPlaceholder
- echoMode: showPassword ? TextInput.Normal : TextInput.Password
- color: WifiModule.Style.textColor
- placeholderTextColor: WifiModule.Style.inputPlaceholderColor
- font.pixelSize: WifiModule.Style.fontSizeNormal
- enabled: selectedSsid !== "" || showHiddenNetwork
- opacity: 1
+ ColumnLayout {
+ visible: root.jelszoKell
+ Layout.fillWidth: true
+ spacing: 6
- background: Rectangle {
- color: passField.enabled ? WifiModule.Style.inputBackgroundColor : WifiModule.Style.inputDisabledColor
- radius: WifiModule.Style.borderRadius
- border.color: passField.focus ? WifiModule.Style.inputFocusBorderColor : WifiModule.Style.inputBorderColor
- border.width: 1
- }
- }
+ Text {
+ text: root.t.password
+ color: Stilus.szovegHalvany
+ font.family: Stilus.font
+ font.pixelSize: 12
+ }
- Button {
- id: showPasswordButton
- anchors.right: parent.right
- anchors.rightMargin: 8
- anchors.verticalCenter: parent.verticalCenter
- height: 32
- text: showPassword ? WifiModule.Translations.hidePassword : WifiModule.Translations.showPassword
- enabled: passField.enabled
- onClicked: showPassword = !showPassword
+ JelszoMezo {
+ id: jelszoMezo
+ Layout.fillWidth: true
+ reveal: root.jelszoLatszik
+ revealName: root.t.showPassword
+ onRevealClicked: root.jelszoLatszik = !root.jelszoLatszik
+ onAccepted: csatlakozGomb.clicked()
+ }
+ }
- background: Rectangle {
- color: parent.hovered ? WifiModule.Style.buttonSecondaryHoverColor : WifiModule.Style.buttonSecondaryColor
- radius: 4
- }
+ Button {
+ id: csatlakozGomb
+ Layout.fillWidth: true
+ implicitHeight: 44
+ text: root.t.connect
+ enabled: root.ssid !== "" && (!root.jelszoKell || jelszoMezo.text !== "") && !root.csatlakozik
+ onClicked: {
+ if (!enabled)
+ return
+ root.sikertelen = false
+ root.csatlakozik = true
+ nm.connectTo(root.ssid, root.jelszoKell ? jelszoMezo.text : "")
+ }
+ background: Rectangle {
+ color: !csatlakozGomb.enabled ? "transparent" : (csatlakozGomb.hovered ? Stilus.zoldHover : Stilus.zold)
+ border.width: csatlakozGomb.enabled ? 0 : 1
+ border.color: Stilus.keret
+ }
+ contentItem: Text {
+ text: csatlakozGomb.text
+ color: csatlakozGomb.enabled ? Stilus.zoldonSzoveg : Stilus.szovegHalvany
+ font.family: Stilus.font
+ font.pixelSize: 14
+ font.weight: Font.DemiBold
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
- contentItem: Label {
- text: parent.text
- color: parent.enabled ? WifiModule.Style.textColor : WifiModule.Style.textDisabledColor
- font.pixelSize: WifiModule.Style.fontSizeSmall
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
+ Text {
+ Layout.fillWidth: true
+ text: root.t.statusLabel + ": " + root.allapotSzoveg()
+ wrapMode: Text.WordWrap
+ color: nm.connected ? Stilus.zold : (root.sikertelen ? Stilus.sarga : Stilus.szovegHalvany)
+ font.family: Stilus.mono
+ font.pixelSize: 12
+ }
}
}
}
-
- // Connect button
- Button {
- Layout.fillWidth: true
- Layout.preferredHeight: WifiModule.Style.buttonHeight
- text: WifiModule.Translations.connect
- enabled: (selectedSsid !== "" || (showHiddenNetwork && ssidField.text !== "")) &&
- passField.text !== "" && !isConnecting && !nm.connected
-
- onClicked: {
- isConnecting = true
- var ssid = showHiddenNetwork ? ssidField.text : selectedSsid
- nm.connectTo(ssid, passField.text)
- }
-
- background: Rectangle {
- color: parent.enabled ? (parent.hovered ? WifiModule.Style.buttonPrimaryHoverColor : WifiModule.Style.buttonPrimaryColor) : WifiModule.Style.buttonDisabledColor
- radius: WifiModule.Style.borderRadius
- }
-
- contentItem: Label {
- text: parent.text
- color: parent.enabled ? WifiModule.Style.textColor : WifiModule.Style.textDisabledColor
- font.pixelSize: 15
- font.bold: true
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
- }
- }
-
- // Skip info
- Label {
- text: nm.connected ?
- WifiModule.Translations.clickNextToContinue :
- WifiModule.Translations.canSkipWithEthernet
- color: WifiModule.Style.textMutedColor
- font.pixelSize: WifiModule.Style.fontSizeTiny
- Layout.alignment: Qt.AlignHCenter
- horizontalAlignment: Text.AlignHCenter
- }
- }
-
- // Connection state change handler
- Connections {
- target: nm
- function onConnectionChanged() {
- if (nm.connected) {
- isConnecting = false
- }
- }
- function onConnectionFailed(error) {
- isConnecting = false
- console.log("Connection failed: " + error)
- }
- }
-
- // Timer to reset connecting state if it takes too long
- Timer {
- id: connectTimeout
- interval: 30000
- running: isConnecting
- onTriggered: {
- if (!nm.connected) {
- isConnecting = false
- }
- }
}
-} \ No newline at end of file
+}