""" dance_picker_dialog.py — Simpel dans-vælger til danselisten. Viser dansenavn primært. Niveau og koreograf vises som info hvis tilgængeligt. Ingen redigering af metadata — det hører til i tag-editoren i biblioteket. """ from PyQt6.QtWidgets import ( QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QListWidget, QListWidgetItem, ) from PyQt6.QtCore import Qt, QTimer class DancePickerDialog(QDialog): def __init__(self, current_dance: str = "", song_title: str = "", existing_dances: list[str] = None, parent=None): super().__init__(parent) self._chosen_dance = current_dance self._existing_dances = existing_dances or [] self.setWindowTitle("Vælg dans") self.setMinimumWidth(420) self.setFixedWidth(460) self._build_ui(current_dance, song_title) self._load_suggestions("") def _build_ui(self, current_dance: str, song_title: str): layout = QVBoxLayout(self) layout.setContentsMargins(12, 12, 12, 12) layout.setSpacing(8) if song_title: lbl = QLabel(song_title) lbl.setObjectName("track_title") lbl.setWordWrap(True) layout.addWidget(lbl) layout.addWidget(QLabel("Dans:")) self._edit = QLineEdit() self._edit.setText(current_dance) self._edit.setPlaceholderText("Skriv dans-navn...") self._edit.selectAll() self._edit.textChanged.connect(self._on_text_changed) self._edit.returnPressed.connect(self._on_accept) layout.addWidget(self._edit) # Forslagsliste self._list = QListWidget() self._list.setMinimumHeight(200) self._list.itemDoubleClicked.connect(self._on_selected) self._list.itemClicked.connect(self._on_item_clicked) layout.addWidget(self._list) # Info-label — viser niveau/koreograf for valgt dans self._info_lbl = QLabel("") self._info_lbl.setObjectName("result_count") self._info_lbl.setWordWrap(True) layout.addWidget(self._info_lbl) # Debounce timer self._timer = QTimer(self) self._timer.setSingleShot(True) self._timer.setInterval(150) self._timer.timeout.connect( lambda: self._load_suggestions(self._edit.text().strip()) ) # Knapper btn_row = QHBoxLayout() btn_row.addStretch() btn_cancel = QPushButton("Annuller") btn_cancel.clicked.connect(self.reject) btn_row.addWidget(btn_cancel) btn_ok = QPushButton("✓ Vælg") btn_ok.setObjectName("btn_play") btn_ok.clicked.connect(self._on_accept) btn_row.addWidget(btn_ok) layout.addLayout(btn_row) self._edit.setFocus() def _on_text_changed(self): self._timer.start() def _load_suggestions(self, prefix: str): try: from local.local_db import get_dance_suggestions from PyQt6.QtGui import QColor suggestions = get_dance_suggestions(prefix or "", limit=25) self._list.clear() # Allerøverst: mulighed for at fjerne dans no_dance = QListWidgetItem("✕ Ingen dans") no_dance.setForeground(QColor("#5a6070")) no_dance.setData(Qt.ItemDataRole.UserRole, {"name": ""}) self._list.addItem(no_dance) # Øverst: danse registreret på denne sang if self._existing_dances: # Filtrer på prefix hvis der skrives matching = [d for d in self._existing_dances if not prefix or prefix.lower() in d.lower()] if matching: # Separator-header sep = QListWidgetItem("── Registreret på denne sang ──") sep.setForeground(QColor("#5a6070")) sep.setFlags(Qt.ItemFlag.ItemIsEnabled) # synlig men ikke valgbar sep.setData(Qt.ItemDataRole.UserRole, None) self._list.addItem(sep) for name in matching: item = QListWidgetItem(f"★ {name}") item.setData(Qt.ItemDataRole.UserRole, {"name": name}) item.setForeground(QColor("#e8a020")) self._list.addItem(item) # Separator for alle danse if suggestions: sep2 = QListWidgetItem("── Alle danse ──") sep2.setForeground(QColor("#5a6070")) sep2.setFlags(Qt.ItemFlag.ItemIsEnabled) # synlig men ikke valgbar sep2.setData(Qt.ItemDataRole.UserRole, None) self._list.addItem(sep2) for s in suggestions: s = dict(s) name = s["name"] level = s.get("level_name") or "" choreo = s.get("choreographer") or "" parts = [name] if level: parts.append(level) if choreo: parts.append(choreo) label = " / ".join(parts) item = QListWidgetItem(label) item.setData(Qt.ItemDataRole.UserRole, { "name": name, "level": level, "choreo": choreo, }) self._list.addItem(item) except Exception as e: import logging logging.getLogger(__name__).warning(f'Dans-forslag fejl: {e}', exc_info=True) def _on_item_clicked(self, item: QListWidgetItem): data = item.data(Qt.ItemDataRole.UserRole) if not data: # separator — ignorer return name = data.get("name", "") level = data.get("level", "") choreo = data.get("choreo", "") self._edit.setText(name) # Vis info parts = [] if level: parts.append(level) if choreo: parts.append(choreo) self._info_lbl.setText(" · ".join(parts) if parts else "") def _on_selected(self, item: QListWidgetItem): data = item.data(Qt.ItemDataRole.UserRole) if not data: # separator return self._on_item_clicked(item) self._on_accept() def _on_accept(self): self._chosen_dance = self._edit.text().strip() self.accept() # tillad tom streng = ingen dans def get_dance(self) -> str: return self._chosen_dance # Behold get_choreo for bagudkompatibilitet — returnerer altid "" def get_choreo(self) -> str: return ""