linux.sipsoftphone/ui/login_dialog.py
data 48ddb4b4af Initiales Release: SIP Softphone für FreePBX/Asterisk
PySide6/PJSUA2-basiertes Desktop-Softphone mit:
- SIP-Telefonie (Anrufe, DTMF, Halten, Transfer, Konferenz)
- CardDAV-Kontaktsync mit Write-Back (Multi-Account)
- Kontaktverwaltung mit Suche und Bearbeiten-Dialog
- Anrufliste mit Namensauflösung
- Favoriten-Panel (manuell + häufig angerufen)
- BLF-Panel (SIP Presence Monitoring)
- Responsives Layout (kompakt/erweitert)
- Click-to-Call (tel:/sip: URI via D-Bus)
- KDE-Integration (Tray, Benachrichtigungen)
- PipeWire/PulseAudio Audio-Routing
- AppImage Build-Support (PyInstaller + appimagetool)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 13:18:54 +01:00

130 lines
4.4 KiB
Python

"""Login-Dialog - SIP-Zugangsdaten beim ersten Start eingeben."""
from PySide6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QFormLayout,
QLineEdit, QPushButton, QCheckBox, QLabel, QSpinBox,
)
from PySide6.QtCore import Qt
from PySide6.QtGui import QIntValidator
class LoginDialog(QDialog):
"""Dialog zur Eingabe der SIP-Zugangsdaten."""
def __init__(self, config_manager, parent=None):
super().__init__(parent)
self._config = config_manager
self.setWindowTitle("SIP-Anmeldung")
self.setMinimumWidth(380)
self.setModal(True)
self._ui_aufbauen()
self._werte_laden()
def _ui_aufbauen(self):
layout = QVBoxLayout(self)
# Titel
titel = QLabel("FreePBX Verbindung einrichten")
titel.setStyleSheet("font-size: 14px; font-weight: bold; margin-bottom: 8px;")
layout.addWidget(titel)
# Formular
form = QFormLayout()
self.server_eingabe = QLineEdit()
self.server_eingabe.setPlaceholderText("z.B. 192.168.154.242")
form.addRow("Server:", self.server_eingabe)
self.port_eingabe = QSpinBox()
self.port_eingabe.setRange(1, 65535)
self.port_eingabe.setValue(5060)
form.addRow("Port:", self.port_eingabe)
self.extension_eingabe = QLineEdit()
self.extension_eingabe.setPlaceholderText("z.B. 200")
self.extension_eingabe.setValidator(QIntValidator(1, 99999))
form.addRow("Extension:", self.extension_eingabe)
self.passwort_eingabe = QLineEdit()
self.passwort_eingabe.setEchoMode(QLineEdit.EchoMode.Password)
self.passwort_eingabe.setPlaceholderText("SIP-Passwort")
form.addRow("Passwort:", self.passwort_eingabe)
layout.addLayout(form)
# Speichern-Option
self.speichern_check = QCheckBox("Zugangsdaten speichern")
self.speichern_check.setChecked(True)
layout.addWidget(self.speichern_check)
# Buttons
btn_layout = QHBoxLayout()
self.verbinden_btn = QPushButton("Verbinden")
self.verbinden_btn.setDefault(True)
self.abbrechen_btn = QPushButton("Abbrechen")
self.verbinden_btn.clicked.connect(self._verbinden)
self.abbrechen_btn.clicked.connect(self.reject)
btn_layout.addStretch()
btn_layout.addWidget(self.abbrechen_btn)
btn_layout.addWidget(self.verbinden_btn)
layout.addLayout(btn_layout)
# Enter-Taste zum Verbinden
self.passwort_eingabe.returnPressed.connect(self._verbinden)
def _werte_laden(self):
"""Gespeicherte Werte aus Config laden."""
sip = self._config.sip
if sip.get("server"):
self.server_eingabe.setText(sip["server"])
if sip.get("port"):
self.port_eingabe.setValue(sip["port"])
if sip.get("extension"):
self.extension_eingabe.setText(sip["extension"])
if sip.get("passwort"):
self.passwort_eingabe.setText(sip["passwort"])
def _verbinden(self):
"""Eingaben validieren und Dialog schließen."""
# Pflichtfelder prüfen
if not self.server_eingabe.text().strip():
self.server_eingabe.setFocus()
self.server_eingabe.setStyleSheet("border: 1px solid red;")
return
if not self.extension_eingabe.text().strip():
self.extension_eingabe.setFocus()
self.extension_eingabe.setStyleSheet("border: 1px solid red;")
return
if not self.passwort_eingabe.text():
self.passwort_eingabe.setFocus()
self.passwort_eingabe.setStyleSheet("border: 1px solid red;")
return
# Config aktualisieren
self._config.set("sip", "server", self.server_eingabe.text().strip())
self._config.set("sip", "port", self.port_eingabe.value())
self._config.set("sip", "extension", self.extension_eingabe.text().strip())
self._config.set("sip", "passwort", self.passwort_eingabe.text())
if self.speichern_check.isChecked():
self._config.speichern()
self.accept()
@property
def server(self):
return self.server_eingabe.text().strip()
@property
def port(self):
return self.port_eingabe.value()
@property
def extension(self):
return self.extension_eingabe.text().strip()
@property
def passwort(self):
return self.passwort_eingabe.text()