"""Favoriten-Panel - Manuelle Favoriten + häufig angerufene Nummern.""" from collections import Counter from PySide6.QtWidgets import ( QWidget, QVBoxLayout, QLabel, QPushButton, QScrollArea, QSizePolicy, ) from PySide6.QtCore import Signal, Qt from PySide6.QtGui import QFont class FavoritenPanel(QWidget): """Kompaktes Panel mit Favoriten und häufig angerufenen Nummern.""" # Signal: Nummer zum Anrufen anrufen = Signal(str) # Signal: Favoriten-Liste hat sich geändert favoriten_geaendert = Signal() def __init__(self, config_manager, parent=None): super().__init__(parent) self._config = config_manager self._kontakte_liste = [] # Für Namensauflösung self._ui_aufbauen() def _ui_aufbauen(self): layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(2) # Überschrift titel = QLabel("Favoriten") titel_font = QFont() titel_font.setPointSize(11) titel_font.setBold(True) titel.setFont(titel_font) titel.setStyleSheet("padding: 4px;") layout.addWidget(titel) # Scrollbarer Bereich für die Buttons scroll = QScrollArea() scroll.setWidgetResizable(True) scroll.setFrameShape(QScrollArea.Shape.NoFrame) scroll.setHorizontalScrollBarPolicy( Qt.ScrollBarPolicy.ScrollBarAlwaysOff) self._inhalt = QWidget() self._inhalt_layout = QVBoxLayout(self._inhalt) self._inhalt_layout.setContentsMargins(0, 0, 0, 0) self._inhalt_layout.setSpacing(2) self._inhalt_layout.addStretch() scroll.setWidget(self._inhalt) layout.addWidget(scroll) def aktualisieren(self): """Favoriten-Anzeige komplett neu aufbauen.""" # Alte Buttons entfernen while self._inhalt_layout.count() > 1: # Stretch behalten item = self._inhalt_layout.takeAt(0) if item.widget(): item.widget().deleteLater() max_anzeige = ( self._config.get("favoriten", "max_anzeige") or 10) # Manuelle Favoriten manuell = self._config.get("favoriten", "manuell") or [] for fav in manuell[:max_anzeige]: name = fav.get("name", "") nummer = fav.get("nummer", "") if nummer: self._button_hinzufuegen(name, nummer, manuell=True) # Häufig angerufen (Rest auffüllen) rest = max_anzeige - len(manuell) if rest > 0: haeufige = self._haeufige_nummern(rest, manuell) if haeufige and manuell: # Trennlinie trenn = QLabel("Häufig angerufen") trenn.setStyleSheet( "color: #888; font-size: 10px; padding: 6px 4px 2px;") self._inhalt_layout.insertWidget( self._inhalt_layout.count() - 1, trenn) for nummer, anzahl in haeufige: name = self._name_fuer_nummer(nummer) self._button_hinzufuegen( name or nummer, nummer, manuell=False) def _button_hinzufuegen(self, name, nummer, manuell=False): """Einen Favoriten-Button ins Layout einfügen.""" if name and name != nummer: text = f"{name}\n{nummer}" else: text = nummer farbe = "#FFD700" if manuell else "#ddd" hover_bg = "rgba(255,215,0,0.12)" if manuell else "rgba(76,175,80,0.12)" btn = QPushButton(text) btn.setStyleSheet( f"QPushButton {{ " f" text-align: left; padding: 8px 10px; " f" font-size: 12px; border: 1px solid #555; " f" border-radius: 6px; background: rgba(255,255,255,0.04); " f" color: {farbe}; " f"}}" f"QPushButton:hover {{ " f" background: {hover_bg}; border-color: {farbe}; " f"}}" f"QPushButton:pressed {{ " f" background: rgba(255,255,255,0.1); " f"}}" ) btn.setCursor(Qt.CursorShape.PointingHandCursor) btn.setSizePolicy( QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) btn.setMinimumHeight(40 if "\n" in text else 34) btn.setToolTip(f"Anrufen: {nummer}") btn.clicked.connect( lambda checked, n=nummer: self.anrufen.emit(n)) # Vor dem Stretch einfügen self._inhalt_layout.insertWidget( self._inhalt_layout.count() - 1, btn) def _haeufige_nummern(self, limit, manuell_favoriten): """Top-N häufig angerufene Nummern aus der Anrufliste berechnen.""" anrufe = self._config.anrufliste_laden() if not anrufe: return [] # Manuelle Favoriten-Nummern (zum Ausschließen) manuell_nummern = { f.get("nummer", "") for f in manuell_favoriten} # Zählen zaehler = Counter() for anruf in anrufe: nummer = anruf.get("nummer", "") if nummer and nummer not in manuell_nummern: zaehler[nummer] += 1 return zaehler.most_common(limit) def _name_fuer_nummer(self, nummer): """Name für eine Nummer in der Kontaktliste suchen.""" for kontakt in self._kontakte_liste: nummern = kontakt.get("nummern", {}) if nummer in nummern.values(): return kontakt.get("name", "") if kontakt.get("nummer") == nummer: return kontakt.get("name", "") return "" def kontakte_setzen(self, kontakte): """Kontaktliste für die Namensauflösung setzen.""" self._kontakte_liste = kontakte or [] def favorit_hinzufuegen(self, name, nummer): """Kontakt als manuellen Favoriten hinzufügen.""" manuell = self._config.get("favoriten", "manuell") or [] # Duplikat prüfen for fav in manuell: if fav.get("nummer") == nummer: return # Schon vorhanden manuell.append({"name": name, "nummer": nummer}) self._config.set("favoriten", "manuell", manuell) self._config.speichern() self.aktualisieren() self.favoriten_geaendert.emit() def favorit_entfernen(self, nummer): """Kontakt aus manuellen Favoriten entfernen.""" manuell = self._config.get("favoriten", "manuell") or [] manuell = [f for f in manuell if f.get("nummer") != nummer] self._config.set("favoriten", "manuell", manuell) self._config.speichern() self.aktualisieren() self.favoriten_geaendert.emit() def ist_favorit(self, nummer): """Prüft ob eine Nummer als manueller Favorit gespeichert ist.""" manuell = self._config.get("favoriten", "manuell") or [] return any(f.get("nummer") == nummer for f in manuell)