Bedre sync
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
"""
|
||||
dance_picker_dialog.py — Dialog til at vælge dans og koreograf med autoudfyld.
|
||||
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 (
|
||||
@@ -10,18 +12,18 @@ from PyQt6.QtCore import Qt, QTimer
|
||||
|
||||
|
||||
class DancePickerDialog(QDialog):
|
||||
def __init__(self, current_dance: str = "", current_choreo: str = "",
|
||||
song_title: str = "", parent=None):
|
||||
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._chosen_choreo = current_choreo
|
||||
self._existing_dances = existing_dances or []
|
||||
self.setWindowTitle("Vælg dans")
|
||||
self.setMinimumWidth(400)
|
||||
self.setFixedWidth(440)
|
||||
self._build_ui(current_dance, current_choreo, song_title)
|
||||
self._load_dance_suggestions("")
|
||||
self.setMinimumWidth(420)
|
||||
self.setFixedWidth(460)
|
||||
self._build_ui(current_dance, song_title)
|
||||
self._load_suggestions("")
|
||||
|
||||
def _build_ui(self, current_dance: str, current_choreo: str, song_title: str):
|
||||
def _build_ui(self, current_dance: str, song_title: str):
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(12, 12, 12, 12)
|
||||
layout.setSpacing(8)
|
||||
@@ -32,65 +34,38 @@ class DancePickerDialog(QDialog):
|
||||
lbl.setWordWrap(True)
|
||||
layout.addWidget(lbl)
|
||||
|
||||
# ── Dans ──────────────────────────────────────────────────────────────
|
||||
lbl2 = QLabel("Dans:")
|
||||
lbl2.setObjectName("track_meta")
|
||||
layout.addWidget(lbl2)
|
||||
layout.addWidget(QLabel("Dans:"))
|
||||
|
||||
self._edit_dance = QLineEdit()
|
||||
self._edit_dance.setText(current_dance)
|
||||
self._edit_dance.setPlaceholderText("Skriv dans-navn...")
|
||||
self._edit_dance.selectAll()
|
||||
self._edit_dance.textChanged.connect(self._on_dance_text_changed)
|
||||
self._edit_dance.returnPressed.connect(lambda: self._edit_choreo.setFocus())
|
||||
layout.addWidget(self._edit_dance)
|
||||
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)
|
||||
|
||||
self._dance_list = QListWidget()
|
||||
self._dance_list.setMaximumHeight(160)
|
||||
self._dance_list.itemDoubleClicked.connect(self._on_dance_selected)
|
||||
self._dance_list.itemClicked.connect(
|
||||
lambda item: self._edit_dance.setText(
|
||||
item.data(Qt.ItemDataRole.UserRole) or item.text().split(" / ")[0]
|
||||
)
|
||||
)
|
||||
layout.addWidget(self._dance_list)
|
||||
# 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)
|
||||
|
||||
# ── Koreograf ─────────────────────────────────────────────────────────
|
||||
lbl3 = QLabel("Koreograf (valgfri):")
|
||||
lbl3.setObjectName("track_meta")
|
||||
layout.addWidget(lbl3)
|
||||
# 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)
|
||||
|
||||
self._edit_choreo = QLineEdit()
|
||||
self._edit_choreo.setText(current_choreo)
|
||||
self._edit_choreo.setPlaceholderText("Koreografens navn...")
|
||||
self._edit_choreo.textChanged.connect(self._on_choreo_text_changed)
|
||||
self._edit_choreo.returnPressed.connect(self._on_accept)
|
||||
layout.addWidget(self._edit_choreo)
|
||||
|
||||
self._choreo_list = QListWidget()
|
||||
self._choreo_list.setMaximumHeight(100)
|
||||
self._choreo_list.itemDoubleClicked.connect(self._on_choreo_selected)
|
||||
self._choreo_list.itemClicked.connect(
|
||||
lambda item: self._edit_choreo.setText(item.text())
|
||||
)
|
||||
layout.addWidget(self._choreo_list)
|
||||
|
||||
# ── Debounce timere ───────────────────────────────────────────────────
|
||||
self._dance_timer = QTimer(self)
|
||||
self._dance_timer.setSingleShot(True)
|
||||
self._dance_timer.setInterval(200)
|
||||
self._dance_timer.timeout.connect(
|
||||
lambda: self._load_dance_suggestions(self._edit_dance.text().strip())
|
||||
# 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())
|
||||
)
|
||||
|
||||
self._choreo_timer = QTimer(self)
|
||||
self._choreo_timer.setSingleShot(True)
|
||||
self._choreo_timer.setInterval(200)
|
||||
self._choreo_timer.timeout.connect(
|
||||
lambda: self._load_choreo_suggestions(self._edit_choreo.text().strip())
|
||||
)
|
||||
|
||||
# ── Knapper ───────────────────────────────────────────────────────────
|
||||
# Knapper
|
||||
btn_row = QHBoxLayout()
|
||||
btn_row.addStretch()
|
||||
btn_cancel = QPushButton("Annuller")
|
||||
@@ -102,62 +77,73 @@ class DancePickerDialog(QDialog):
|
||||
btn_row.addWidget(btn_ok)
|
||||
layout.addLayout(btn_row)
|
||||
|
||||
self._edit_dance.setFocus()
|
||||
self._edit.setFocus()
|
||||
|
||||
def _on_dance_text_changed(self):
|
||||
self._dance_timer.start()
|
||||
def _on_text_changed(self):
|
||||
self._timer.start()
|
||||
|
||||
def _on_choreo_text_changed(self):
|
||||
self._choreo_timer.start()
|
||||
|
||||
def _load_dance_suggestions(self, prefix: str):
|
||||
def _load_suggestions(self, prefix: str):
|
||||
try:
|
||||
from local.local_db import get_dance_suggestions
|
||||
suggestions = get_dance_suggestions(prefix or "", limit=20)
|
||||
self._dance_list.clear()
|
||||
suggestions = get_dance_suggestions(prefix or "", limit=25)
|
||||
self._list.clear()
|
||||
|
||||
# Vis eksisterende danse øverst hvis ingen prefix
|
||||
if not prefix and self._existing_dances:
|
||||
for name in self._existing_dances:
|
||||
item = QListWidgetItem(f"★ {name}")
|
||||
item.setData(Qt.ItemDataRole.UserRole, {"name": name})
|
||||
item.setForeground(__import__('PyQt6.QtGui', fromlist=['QColor']).QColor("#e8a020"))
|
||||
self._list.addItem(item)
|
||||
|
||||
for s in suggestions:
|
||||
label = f"{s['name']} / {s['level_name']}" if s.get("level_name") else s["name"]
|
||||
if s.get("choreographer"):
|
||||
label += f" ({s['choreographer']})"
|
||||
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, s["name"])
|
||||
item.setData(Qt.ItemDataRole.UserRole + 1, s.get("choreographer", ""))
|
||||
self._dance_list.addItem(item)
|
||||
except Exception:
|
||||
pass
|
||||
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 _load_choreo_suggestions(self, prefix: str):
|
||||
try:
|
||||
from local.local_db import get_choreographer_suggestions
|
||||
suggestions = get_choreographer_suggestions(prefix or "", limit=15)
|
||||
self._choreo_list.clear()
|
||||
for name in suggestions:
|
||||
self._choreo_list.addItem(QListWidgetItem(name))
|
||||
except Exception:
|
||||
pass
|
||||
def _on_item_clicked(self, item: QListWidgetItem):
|
||||
data = item.data(Qt.ItemDataRole.UserRole) or {}
|
||||
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_dance_selected(self, item: QListWidgetItem):
|
||||
name = item.data(Qt.ItemDataRole.UserRole) or item.text().split(" / ")[0]
|
||||
choreo = item.data(Qt.ItemDataRole.UserRole + 1) or ""
|
||||
self._edit_dance.setText(name)
|
||||
if choreo and not self._edit_choreo.text().strip():
|
||||
self._edit_choreo.setText(choreo)
|
||||
self._chosen_dance = name
|
||||
self._chosen_choreo = self._edit_choreo.text().strip()
|
||||
self.accept()
|
||||
|
||||
def _on_choreo_selected(self, item: QListWidgetItem):
|
||||
self._edit_choreo.setText(item.text())
|
||||
self._choreo_list.clear()
|
||||
def _on_selected(self, item: QListWidgetItem):
|
||||
self._on_item_clicked(item)
|
||||
self._on_accept()
|
||||
|
||||
def _on_accept(self):
|
||||
self._chosen_dance = self._edit_dance.text().strip()
|
||||
self._chosen_choreo = self._edit_choreo.text().strip()
|
||||
self._chosen_dance = self._edit.text().strip()
|
||||
if self._chosen_dance:
|
||||
self.accept()
|
||||
|
||||
def get_dance(self) -> str:
|
||||
return self._chosen_dance
|
||||
|
||||
# Behold get_choreo for bagudkompatibilitet — returnerer altid ""
|
||||
def get_choreo(self) -> str:
|
||||
return self._chosen_choreo
|
||||
return ""
|
||||
Reference in New Issue
Block a user