Files
LinedanceAfspiller/linedance-app/ui/dance_info_dialog.py
2026-04-21 16:47:33 +02:00

222 lines
8.3 KiB
Python

"""
dance_info_dialog.py — Rediger info om en dans: koreograf, video, step sheet, noter.
"""
from PyQt6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
QPushButton, QTextEdit, QComboBox, QFrame, QMessageBox,
QTabWidget, QWidget,
)
from PyQt6.QtCore import Qt, QUrl
from PyQt6.QtGui import QDesktopServices
class DanceInfoDialog(QDialog):
"""Vis og rediger info om danse tilknyttet en sang."""
def __init__(self, song: dict, parent=None):
super().__init__(parent)
self._song = song
self._dances = [] # [{dance_id, name, level_name, ...}]
self._current_idx = 0
self.setWindowTitle(f"Dans-info — {song.get('title', '')}")
self.setMinimumSize(560, 420)
self.resize(620, 460)
self._load_dances()
self._build_ui()
if self._dances:
self._show_dance(0)
def _load_dances(self):
try:
from local.local_db import get_db
with get_db() as conn:
rows = conn.execute("""
SELECT d.id, d.name, d.choreographer,
d.video_url, d.stepsheet_url, d.notes,
dl.name as level_name
FROM song_dances sd
JOIN dances d ON d.id = sd.dance_id
LEFT JOIN dance_levels dl ON dl.id = d.level_id
WHERE sd.song_id=? ORDER BY sd.dance_order
""", (self._song.get("id"),)).fetchall()
for row in rows:
self._dances.append({
"dance_id": row["id"],
"name": row["name"],
"level_name": row["level_name"] or "",
"choreographer": row["choreographer"] or "",
"video_url": row["video_url"] or "",
"stepsheet_url": row["stepsheet_url"] or "",
"notes": row["notes"] or "",
"is_alt": False,
})
alt_rows = conn.execute("""
SELECT d.id, d.name, d.choreographer,
d.video_url, d.stepsheet_url, d.notes,
dl.name as level_name
FROM song_alt_dances sad
JOIN dances d ON d.id = sad.dance_id
LEFT JOIN dance_levels dl ON dl.id = d.level_id
WHERE sad.song_id=? ORDER BY d.name
""", (self._song.get("id"),)).fetchall()
for row in alt_rows:
self._dances.append({
"dance_id": row["id"],
"name": row["name"],
"level_name": row["level_name"] or "",
"choreographer": row["choreographer"] or "",
"video_url": row["video_url"] or "",
"stepsheet_url": row["stepsheet_url"] or "",
"notes": row["notes"] or "",
"is_alt": True,
})
except Exception as e:
print(f"DanceInfoDialog load fejl: {e}")
def _build_ui(self):
layout = QVBoxLayout(self)
layout.setContentsMargins(12, 12, 12, 12)
layout.setSpacing(8)
# Sang-info
info = QFrame()
info.setObjectName("track_display")
il = QHBoxLayout(info)
il.setContentsMargins(10, 8, 10, 8)
lbl = QLabel(self._song.get("title", ""))
lbl.setObjectName("track_title")
il.addWidget(lbl, stretch=1)
layout.addWidget(info)
if not self._dances:
layout.addWidget(QLabel("Ingen danse tagget på denne sang."))
btn_close = QPushButton("Luk")
btn_close.clicked.connect(self.reject)
layout.addWidget(btn_close)
return
# Dans-vælger
top = QHBoxLayout()
top.addWidget(QLabel("Dans:"))
self._dance_combo = QComboBox()
for d in self._dances:
prefix = "" if d["is_alt"] else ""
lvl = f" / {d['level_name']}" if d["level_name"] else ""
self._dance_combo.addItem(f"{prefix}{d['name']}{lvl}")
self._dance_combo.currentIndexChanged.connect(self._on_dance_changed)
top.addWidget(self._dance_combo, stretch=1)
layout.addLayout(top)
# Formular
form_frame = QFrame()
form_frame.setObjectName("track_display")
form = QVBoxLayout(form_frame)
form.setContentsMargins(12, 10, 12, 10)
form.setSpacing(8)
# Koreograf
row1 = QHBoxLayout()
row1.addWidget(QLabel("Koreograf:"))
self._choreo = QLineEdit()
self._choreo.setPlaceholderText("Koreografens navn...")
row1.addWidget(self._choreo)
form.addLayout(row1)
# Step sheet URL
row2 = QHBoxLayout()
row2.addWidget(QLabel("Step sheet:"))
self._stepsheet = QLineEdit()
self._stepsheet.setPlaceholderText("https://www.copperknob.co.uk/...")
row2.addWidget(self._stepsheet)
btn_ss = QPushButton("")
btn_ss.setFixedWidth(28)
btn_ss.setToolTip("Åbn i browser")
btn_ss.clicked.connect(lambda: self._open_url(self._stepsheet.text()))
row2.addWidget(btn_ss)
form.addLayout(row2)
# Video URL
row3 = QHBoxLayout()
row3.addWidget(QLabel("Video:"))
self._video = QLineEdit()
self._video.setPlaceholderText("https://www.youtube.com/...")
row3.addWidget(self._video)
btn_v = QPushButton("")
btn_v.setFixedWidth(28)
btn_v.setToolTip("Åbn i browser")
btn_v.clicked.connect(lambda: self._open_url(self._video.text()))
row3.addWidget(btn_v)
form.addLayout(row3)
# Noter
form.addWidget(QLabel("Noter:"))
self._notes = QTextEdit()
self._notes.setPlaceholderText("Egne noter om dansen...")
self._notes.setMaximumHeight(80)
form.addWidget(self._notes)
layout.addWidget(form_frame, stretch=1)
# Knapper
btn_row = QHBoxLayout()
btn_row.addStretch()
btn_cancel = QPushButton("Luk")
btn_cancel.clicked.connect(self.reject)
btn_row.addWidget(btn_cancel)
btn_save = QPushButton("💾 Gem")
btn_save.setObjectName("btn_play")
btn_save.clicked.connect(self._save)
btn_row.addWidget(btn_save)
layout.addLayout(btn_row)
def _on_dance_changed(self, idx: int):
self._save_to_cache(self._current_idx)
self._current_idx = idx
self._show_dance(idx)
def _show_dance(self, idx: int):
if not 0 <= idx < len(self._dances):
return
d = self._dances[idx]
self._choreo.setText(d["choreographer"])
self._stepsheet.setText(d["stepsheet_url"])
self._video.setText(d["video_url"])
self._notes.setPlainText(d["notes"])
def _save_to_cache(self, idx: int):
"""Gem UI-værdier til cache så de ikke mistes ved dans-skift."""
if not 0 <= idx < len(self._dances):
return
self._dances[idx]["choreographer"] = self._choreo.text().strip()
self._dances[idx]["stepsheet_url"] = self._stepsheet.text().strip()
self._dances[idx]["video_url"] = self._video.text().strip()
self._dances[idx]["notes"] = self._notes.toPlainText().strip()
def _save(self):
self._save_to_cache(self._current_idx)
try:
from local.local_db import get_db
with get_db() as conn:
for d in self._dances:
conn.execute("""
UPDATE dances SET choreographer=?, video_url=?,
stepsheet_url=?, notes=? WHERE id=?
""", (d["choreographer"], d["video_url"],
d["stepsheet_url"], d["notes"], d["dance_id"]))
self.accept()
except Exception as e:
QMessageBox.warning(self, "Fejl", f"Kunne ikke gemme: {e}")
def _open_url(self, url: str):
url = url.strip()
if not url:
return
if not url.startswith("http"):
url = "https://" + url
QDesktopServices.openUrl(QUrl(url))