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>
130 lines
4.4 KiB
Python
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()
|