Næste version
This commit is contained in:
@@ -5,7 +5,7 @@ playlist_panel.py — Danseliste med Ny/Gem/Hent knapper, autogem og event-overb
|
||||
from PyQt6.QtWidgets import (
|
||||
QWidget, QVBoxLayout, QListWidget, QListWidgetItem,
|
||||
QLabel, QHBoxLayout, QPushButton, QMenu, QAbstractItemView,
|
||||
QMessageBox, QInputDialog,
|
||||
QMessageBox,
|
||||
)
|
||||
from PyQt6.QtCore import Qt, pyqtSignal, QTimer, QByteArray
|
||||
from PyQt6.QtGui import QColor, QDragEnterEvent, QDropEvent
|
||||
@@ -76,6 +76,13 @@ class PlaylistPanel(QWidget):
|
||||
btn_save.clicked.connect(self._save_as)
|
||||
toolbar.addWidget(btn_save)
|
||||
|
||||
self._btn_save_current = QPushButton("💾 Gem")
|
||||
self._btn_save_current.setFixedHeight(26)
|
||||
self._btn_save_current.setToolTip("Gem ændringer til den indlæste liste")
|
||||
self._btn_save_current.clicked.connect(self._save_current)
|
||||
self._btn_save_current.setEnabled(False)
|
||||
toolbar.addWidget(self._btn_save_current)
|
||||
|
||||
btn_load = QPushButton("📂 Hent...")
|
||||
btn_load.setFixedHeight(26)
|
||||
btn_load.setToolTip("Hent en tidligere gemt danseliste")
|
||||
@@ -106,8 +113,24 @@ class PlaylistPanel(QWidget):
|
||||
self._lbl_progress.setObjectName("result_count")
|
||||
ctrl.addWidget(self._lbl_progress)
|
||||
|
||||
btn_info = QPushButton("ℹ")
|
||||
btn_info.setFixedSize(24, 28)
|
||||
btn_info.setToolTip("Danseliste-info: samlet tid, pause-tid m.m.")
|
||||
btn_info.clicked.connect(self._show_playlist_info)
|
||||
ctrl.addWidget(btn_info)
|
||||
|
||||
layout.addLayout(ctrl)
|
||||
|
||||
# Pause-tid per dans (skjult men kan vises via info)
|
||||
try:
|
||||
from ui.settings_dialog import load_settings
|
||||
s = load_settings()
|
||||
self._pause_seconds = s.get("between_seconds", 60)
|
||||
self._workshop_seconds = s.get("workshop_minutes", 10) * 60
|
||||
except Exception:
|
||||
self._pause_seconds = 60
|
||||
self._workshop_seconds = 600
|
||||
|
||||
# ── Liste ─────────────────────────────────────────────────────────────
|
||||
self._list = QListWidget()
|
||||
self._list.setObjectName("playlist_list")
|
||||
@@ -201,6 +224,11 @@ class PlaylistPanel(QWidget):
|
||||
|
||||
def _on_rows_moved(self, parent, start, end, dest, dest_row):
|
||||
"""Opdater _songs og _statuses når en sang flyttes via drag."""
|
||||
# Husk hvilken sang der er aktiv
|
||||
current_song_id = None
|
||||
if 0 <= self._current_idx < len(self._songs):
|
||||
current_song_id = self._songs[self._current_idx].get("id")
|
||||
|
||||
new_songs = []
|
||||
new_statuses = []
|
||||
for i in range(self._list.count()):
|
||||
@@ -210,17 +238,20 @@ class PlaylistPanel(QWidget):
|
||||
new_statuses.append(self._statuses[old_idx])
|
||||
self._songs = new_songs
|
||||
self._statuses = new_statuses
|
||||
self._current_idx = -1
|
||||
|
||||
# Gendan current_idx til den sang der stadig spiller
|
||||
if current_song_id:
|
||||
for i, s in enumerate(self._songs):
|
||||
if s.get("id") == current_song_id:
|
||||
self._current_idx = i
|
||||
break
|
||||
else:
|
||||
self._current_idx = -1
|
||||
|
||||
self._song_ended = False
|
||||
self._refresh()
|
||||
self._trigger_autosave()
|
||||
|
||||
# Find første afspilbare sang og udsend signal så afspilleren opdateres
|
||||
ni = self.next_playable_idx()
|
||||
if ni is not None:
|
||||
self._current_idx = ni
|
||||
self._refresh()
|
||||
self.next_song_ready.emit(self._songs[ni])
|
||||
# Emit IKKE next_song_ready — afspilning fortsætter uforstyrret
|
||||
|
||||
# ── Event-state ───────────────────────────────────────────────────────────
|
||||
|
||||
@@ -292,42 +323,95 @@ class PlaylistPanel(QWidget):
|
||||
self._lbl_autosave.setText(f"⚠ gemfejl")
|
||||
pass
|
||||
|
||||
def _save_named_playlist_id(self, pl_id: int | None):
|
||||
"""Gem hvilken navngiven liste der er aktiv — til brug ved næste opstart."""
|
||||
from PyQt6.QtCore import QSettings
|
||||
s = QSettings("LineDance", "Player")
|
||||
if pl_id:
|
||||
s.setValue("session/named_playlist_id", pl_id)
|
||||
else:
|
||||
s.remove("session/named_playlist_id")
|
||||
|
||||
def restore_active_playlist(self):
|
||||
"""Indlæs den sidst aktive liste ved opstart."""
|
||||
"""Gendan senest aktive navngivne liste med event-fremgang ved opstart."""
|
||||
try:
|
||||
from local.local_db import get_db
|
||||
with get_db() as conn:
|
||||
pl = conn.execute(
|
||||
"SELECT id FROM playlists WHERE name=?", (ACTIVE_PLAYLIST_NAME,)
|
||||
).fetchone()
|
||||
if not pl:
|
||||
return False
|
||||
songs_raw = conn.execute("""
|
||||
SELECT s.*, ps.position FROM playlist_songs ps
|
||||
JOIN songs s ON s.id = ps.song_id
|
||||
WHERE ps.playlist_id=? ORDER BY ps.position
|
||||
""", (pl["id"],)).fetchall()
|
||||
songs = []
|
||||
for row in songs_raw:
|
||||
dances = conn.execute(
|
||||
"SELECT dance_name FROM song_dances WHERE song_id=? ORDER BY dance_order",
|
||||
(row["id"],)
|
||||
).fetchall()
|
||||
songs.append({
|
||||
"id": row["id"], "title": row["title"],
|
||||
"artist": row["artist"], "album": row["album"],
|
||||
"bpm": row["bpm"], "duration_sec": row["duration_sec"],
|
||||
"local_path": row["local_path"], "file_format": row["file_format"],
|
||||
"file_missing": bool(row["file_missing"]),
|
||||
"dances": [d["dance_name"] for d in dances],
|
||||
})
|
||||
from PyQt6.QtCore import QSettings
|
||||
s = QSettings("LineDance", "Player")
|
||||
pl_id = s.value("session/named_playlist_id", None, type=int)
|
||||
if not pl_id:
|
||||
return False
|
||||
|
||||
import sqlite3
|
||||
from local.local_db import DB_PATH
|
||||
conn = sqlite3.connect(str(DB_PATH))
|
||||
conn.row_factory = sqlite3.Row
|
||||
|
||||
# Verificer at listen stadig eksisterer
|
||||
pl = conn.execute(
|
||||
"SELECT id, name FROM playlists WHERE id=?", (pl_id,)
|
||||
).fetchone()
|
||||
if not pl:
|
||||
conn.close()
|
||||
return False
|
||||
|
||||
# Hent sange med status, workshop og dans-override
|
||||
songs_raw = conn.execute("""
|
||||
SELECT s.*, ps.position, ps.status,
|
||||
ps.is_workshop, ps.dance_override
|
||||
FROM playlist_songs ps
|
||||
JOIN songs s ON s.id = ps.song_id
|
||||
WHERE ps.playlist_id=? ORDER BY ps.position
|
||||
""", (pl_id,)).fetchall()
|
||||
|
||||
songs = []
|
||||
statuses = []
|
||||
for row in songs_raw:
|
||||
dances = conn.execute("""
|
||||
SELECT d.name FROM song_dances sd
|
||||
JOIN dances d ON d.id = sd.dance_id
|
||||
WHERE sd.song_id=? ORDER BY sd.dance_order
|
||||
""", (row["id"],)).fetchall()
|
||||
dance_names = [d["name"] for d in dances]
|
||||
override = row["dance_override"] or ""
|
||||
active_dance = override if override else (dance_names[0] if dance_names else "")
|
||||
songs.append({
|
||||
"id": row["id"],
|
||||
"title": row["title"],
|
||||
"artist": row["artist"],
|
||||
"album": row["album"],
|
||||
"bpm": row["bpm"],
|
||||
"duration_sec": row["duration_sec"],
|
||||
"local_path": row["local_path"],
|
||||
"file_format": row["file_format"],
|
||||
"file_missing": bool(row["file_missing"]),
|
||||
"dances": dance_names,
|
||||
"active_dance": active_dance,
|
||||
"is_workshop": bool(row["is_workshop"]),
|
||||
})
|
||||
statuses.append(row["status"] or "pending")
|
||||
conn.close()
|
||||
|
||||
if songs:
|
||||
self._songs = songs
|
||||
self._statuses = ["pending"] * len(songs)
|
||||
self._refresh()
|
||||
self._songs = songs
|
||||
self._statuses = statuses
|
||||
self._named_playlist_id = pl_id
|
||||
self._current_idx = -1
|
||||
self._song_ended = False
|
||||
self._btn_save_current.setEnabled(True)
|
||||
self._btn_save_current.setToolTip(f"Gem ændringer til '{pl['name']}'")
|
||||
self._title_label.setText(f"DANSELISTE — {pl['name'].upper()}")
|
||||
self._lbl_autosave.setText("✓ gendannet")
|
||||
self._refresh()
|
||||
|
||||
# Find næste uafspillede og sæt den klar
|
||||
ni = self.next_playable_idx()
|
||||
if ni is not None:
|
||||
self._current_idx = ni
|
||||
self._refresh()
|
||||
self.next_song_ready.emit(self._songs[ni])
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
pass
|
||||
return False
|
||||
|
||||
@@ -346,6 +430,10 @@ class PlaylistPanel(QWidget):
|
||||
self._statuses = []
|
||||
self._current_idx = -1
|
||||
self._song_ended = False
|
||||
self._named_playlist_id = None
|
||||
self._btn_save_current.setEnabled(False)
|
||||
self._btn_save_current.setToolTip("Gem ændringer til den indlæste liste")
|
||||
self._save_named_playlist_id(None)
|
||||
self._title_label.setText("DANSELISTE — NY")
|
||||
self._refresh()
|
||||
self._trigger_autosave()
|
||||
@@ -354,75 +442,88 @@ class PlaylistPanel(QWidget):
|
||||
if not self._songs:
|
||||
QMessageBox.information(self, "Gem", "Danselisten er tom.")
|
||||
return
|
||||
name, ok = QInputDialog.getText(
|
||||
self, "Gem danseliste", "Navn på danselisten:",
|
||||
from ui.playlist_browser import PlaylistBrowserDialog
|
||||
current_name = self._title_label.text().replace("DANSELISTE — ", "").replace("DANSELISTE", "").strip()
|
||||
dialog = PlaylistBrowserDialog(
|
||||
mode="save",
|
||||
current_songs=self._songs,
|
||||
current_name=current_name,
|
||||
parent=self.window()
|
||||
)
|
||||
if not ok or not name.strip():
|
||||
return
|
||||
name = name.strip()
|
||||
try:
|
||||
from local.local_db import create_playlist, add_song_to_playlist
|
||||
pl_id = create_playlist(name)
|
||||
for i, song in enumerate(self._songs, start=1):
|
||||
if song.get("id"):
|
||||
add_song_to_playlist(pl_id, song["id"], position=i)
|
||||
def on_saved(pl_id, name):
|
||||
self._named_playlist_id = pl_id
|
||||
self._title_label.setText(f"DANSELISTE — {name.upper()}")
|
||||
self._lbl_autosave.setText(f"✓ gemt som \"{name}\"")
|
||||
self._btn_save_current.setEnabled(True)
|
||||
self._btn_save_current.setToolTip(f"Gem ændringer til '{name}'")
|
||||
self._save_named_playlist_id(pl_id)
|
||||
dialog.playlist_selected.connect(on_saved)
|
||||
dialog.exec()
|
||||
|
||||
def _save_current(self):
|
||||
"""Gem ændringer tilbage til den aktuelt indlæste navngivne liste."""
|
||||
if not self._named_playlist_id:
|
||||
return
|
||||
if not self._songs:
|
||||
QMessageBox.information(self, "Gem", "Danselisten er tom.")
|
||||
return
|
||||
try:
|
||||
from local.local_db import get_db
|
||||
with get_db() as conn:
|
||||
conn.execute(
|
||||
"DELETE FROM playlist_songs WHERE playlist_id=?",
|
||||
(self._named_playlist_id,)
|
||||
)
|
||||
for i, song in enumerate(self._songs, start=1):
|
||||
if song.get("id"):
|
||||
status = self._statuses[i-1] if i-1 < len(self._statuses) else "pending"
|
||||
conn.execute(
|
||||
"INSERT INTO playlist_songs "
|
||||
"(playlist_id, song_id, position, status) VALUES (?,?,?,?)",
|
||||
(self._named_playlist_id, song["id"], i, status)
|
||||
)
|
||||
self._lbl_autosave.setText("✓ gemt")
|
||||
except Exception as e:
|
||||
QMessageBox.warning(self, "Fejl", f"Kunne ikke gemme: {e}")
|
||||
|
||||
def _load_dialog(self):
|
||||
"""Vis liste af gemte danselister og lad brugeren vælge."""
|
||||
try:
|
||||
from local.local_db import get_db
|
||||
with get_db() as conn:
|
||||
lists = conn.execute(
|
||||
"SELECT id, name, created_at FROM playlists "
|
||||
"WHERE name != ? ORDER BY created_at DESC",
|
||||
(ACTIVE_PLAYLIST_NAME,)
|
||||
).fetchall()
|
||||
except Exception as e:
|
||||
QMessageBox.warning(self, "Fejl", f"Kunne ikke hente lister: {e}")
|
||||
return
|
||||
|
||||
if not lists:
|
||||
QMessageBox.information(self, "Hent liste", "Ingen gemte danselister fundet.")
|
||||
return
|
||||
|
||||
names = [f"{row['name']} ({row['created_at'][:10]})" for row in lists]
|
||||
choice, ok = QInputDialog.getItem(
|
||||
self, "Hent danseliste", "Vælg en liste:", names, editable=False
|
||||
)
|
||||
if not ok:
|
||||
return
|
||||
|
||||
idx = names.index(choice)
|
||||
pl_id = lists[idx]["id"]
|
||||
pl_name = lists[idx]["name"]
|
||||
from ui.playlist_browser import PlaylistBrowserDialog
|
||||
dialog = PlaylistBrowserDialog(mode="load", parent=self.window())
|
||||
dialog.playlist_selected.connect(self._load_playlist_by_id)
|
||||
dialog.exec()
|
||||
|
||||
def _load_playlist_by_id(self, pl_id: int, pl_name: str):
|
||||
try:
|
||||
from local.local_db import get_db
|
||||
with get_db() as conn:
|
||||
songs_raw = conn.execute("""
|
||||
SELECT s.*, ps.position, ps.status FROM playlist_songs ps
|
||||
SELECT s.*, ps.position, ps.status,
|
||||
ps.is_workshop, ps.dance_override
|
||||
FROM playlist_songs ps
|
||||
JOIN songs s ON s.id = ps.song_id
|
||||
WHERE ps.playlist_id=? ORDER BY ps.position
|
||||
""", (pl_id,)).fetchall()
|
||||
songs = []
|
||||
statuses = []
|
||||
for row in songs_raw:
|
||||
dances = conn.execute(
|
||||
"SELECT dance_name FROM song_dances WHERE song_id=? ORDER BY dance_order",
|
||||
(row["id"],)
|
||||
).fetchall()
|
||||
dances = conn.execute("""
|
||||
SELECT d.name FROM song_dances sd
|
||||
JOIN dances d ON d.id = sd.dance_id
|
||||
WHERE sd.song_id=? ORDER BY sd.dance_order
|
||||
""", (row["id"],)).fetchall()
|
||||
dance_names = [d["name"] for d in dances]
|
||||
# dance_override bestemmer hvilken dans der vises
|
||||
override = row["dance_override"] or ""
|
||||
active_dance = override if override else (dance_names[0] if dance_names else "")
|
||||
songs.append({
|
||||
"id": row["id"], "title": row["title"],
|
||||
"artist": row["artist"], "album": row["album"],
|
||||
"bpm": row["bpm"], "duration_sec": row["duration_sec"],
|
||||
"local_path": row["local_path"], "file_format": row["file_format"],
|
||||
"file_missing": bool(row["file_missing"]),
|
||||
"dances": [d["dance_name"] for d in dances],
|
||||
"dances": dance_names,
|
||||
"active_dance": active_dance,
|
||||
"is_workshop": bool(row["is_workshop"]),
|
||||
})
|
||||
statuses.append(row["status"] or "pending")
|
||||
self._songs = songs
|
||||
@@ -432,6 +533,9 @@ class PlaylistPanel(QWidget):
|
||||
self._named_playlist_id = pl_id
|
||||
self._title_label.setText(f"DANSELISTE — {pl_name.upper()}")
|
||||
self._lbl_autosave.setText("✓ gendannet")
|
||||
self._btn_save_current.setEnabled(True)
|
||||
self._btn_save_current.setToolTip(f"Gem ændringer til '{pl_name}'")
|
||||
self._save_named_playlist_id(pl_id)
|
||||
self._refresh()
|
||||
self._trigger_autosave()
|
||||
except Exception as e:
|
||||
@@ -439,6 +543,94 @@ class PlaylistPanel(QWidget):
|
||||
|
||||
# ── Start event ───────────────────────────────────────────────────────────
|
||||
|
||||
def _show_playlist_info(self):
|
||||
"""Åbn/luk det flydende danseliste-info vindue."""
|
||||
try:
|
||||
if hasattr(self, "_info_window") and self._info_window \
|
||||
and self._info_window.isVisible():
|
||||
self._info_window.close()
|
||||
self._info_window = None
|
||||
return
|
||||
except RuntimeError:
|
||||
self._info_window = None
|
||||
|
||||
# Opdater defaults fra indstillinger ved åbning
|
||||
try:
|
||||
from ui.settings_dialog import load_settings
|
||||
s = load_settings()
|
||||
self._pause_seconds = s.get("between_seconds", 60)
|
||||
self._workshop_seconds = s.get("workshop_minutes", 10) * 60
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
from ui.playlist_info_dialog import PlaylistInfoWindow
|
||||
from PyQt6.QtWidgets import QApplication
|
||||
main = self.window()
|
||||
self._info_window = PlaylistInfoWindow(self, parent=main)
|
||||
QApplication.instance().aboutToQuit.connect(self._info_window.close)
|
||||
if main:
|
||||
geo = main.geometry()
|
||||
self._info_window.move(geo.right() + 10, geo.top() + 100)
|
||||
self._info_window.show()
|
||||
|
||||
def _change_dance(self, idx: int, song: dict):
|
||||
"""Lad brugeren vælge/skrive hvilken dans der vises for dette nummer."""
|
||||
from ui.dance_picker_dialog import DancePickerDialog
|
||||
current = song.get("active_dance", "")
|
||||
if not current:
|
||||
dances = song.get("dances", [])
|
||||
current = dances[0] if dances else ""
|
||||
dlg = DancePickerDialog(
|
||||
current_dance=current,
|
||||
song_title=song.get("title", ""),
|
||||
parent=self.window()
|
||||
)
|
||||
if dlg.exec():
|
||||
chosen = dlg.get_dance()
|
||||
if chosen:
|
||||
song["active_dance"] = chosen
|
||||
self._refresh()
|
||||
self._sync_dance_to_db(idx, song)
|
||||
|
||||
def _sync_dance_to_db(self, idx: int, song: dict):
|
||||
"""Gem dance_override til playlist_songs."""
|
||||
if not self._named_playlist_id:
|
||||
return
|
||||
try:
|
||||
from local.local_db import get_db
|
||||
with get_db() as conn:
|
||||
conn.execute(
|
||||
"UPDATE playlist_songs SET dance_override=? "
|
||||
"WHERE playlist_id=? AND position=?",
|
||||
(song.get("active_dance", ""), self._named_playlist_id, idx + 1)
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _sync_ws_to_db(self, idx: int, song: dict):
|
||||
"""Gem is_workshop til playlist_songs — både navngiven og aktiv liste."""
|
||||
pl_ids = []
|
||||
if self._named_playlist_id:
|
||||
pl_ids.append(self._named_playlist_id)
|
||||
if self._active_playlist_id:
|
||||
pl_ids.append(self._active_playlist_id)
|
||||
if not pl_ids:
|
||||
return
|
||||
try:
|
||||
from local.local_db import get_db
|
||||
with get_db() as conn:
|
||||
for pl_id in pl_ids:
|
||||
conn.execute(
|
||||
"UPDATE playlist_songs SET is_workshop=? "
|
||||
"WHERE playlist_id=? AND position=?",
|
||||
(1 if song.get("is_workshop") else 0, pl_id, idx + 1)
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _on_pause_changed(self, seconds: int):
|
||||
self._pause_seconds = seconds
|
||||
|
||||
def _start_event(self):
|
||||
if not self._songs:
|
||||
return
|
||||
@@ -469,6 +661,7 @@ class PlaylistPanel(QWidget):
|
||||
idx = item.data(Qt.ItemDataRole.UserRole)
|
||||
if idx is None:
|
||||
return
|
||||
song = self._songs[idx] if 0 <= idx < len(self._songs) else None
|
||||
menu = QMenu(self)
|
||||
act_play = menu.addAction("▶ Afspil denne")
|
||||
menu.addSeparator()
|
||||
@@ -476,6 +669,14 @@ class PlaylistPanel(QWidget):
|
||||
act_unplay = menu.addAction("↺ Sæt til ikke afspillet")
|
||||
act_played = menu.addAction("✓ Sæt til afspillet")
|
||||
menu.addSeparator()
|
||||
# Dans-valg
|
||||
act_dance = menu.addAction("💃 Vælg dans...")
|
||||
# Workshop toggle
|
||||
is_ws = song.get("is_workshop", False) if song else False
|
||||
act_ws = menu.addAction("🎓 Fjern workshop" if is_ws else "🎓 Markér som workshop")
|
||||
menu.addSeparator()
|
||||
act_dance_info = menu.addAction("ℹ Dans-info...")
|
||||
menu.addSeparator()
|
||||
act_remove = menu.addAction("✕ Fjern fra liste")
|
||||
action = menu.exec(self._list.mapToGlobal(pos))
|
||||
if action == act_play:
|
||||
@@ -492,6 +693,18 @@ class PlaylistPanel(QWidget):
|
||||
self._statuses[idx] = "played"
|
||||
self.status_changed.emit(idx, "played")
|
||||
self._refresh(); self._trigger_autosave(); self._trigger_event_state_save()
|
||||
elif action == act_dance and song:
|
||||
self._change_dance(idx, song)
|
||||
elif action == act_ws and song:
|
||||
song["is_workshop"] = not song.get("is_workshop", False)
|
||||
self._sync_ws_to_db(idx, song)
|
||||
self._refresh()
|
||||
self.playlist_changed.emit()
|
||||
elif action == act_dance_info:
|
||||
if song:
|
||||
from ui.dance_info_dialog import DanceInfoDialog
|
||||
dlg = DanceInfoDialog(song, parent=self.window())
|
||||
dlg.exec()
|
||||
elif action == act_remove:
|
||||
self._songs.pop(idx)
|
||||
self._statuses.pop(idx)
|
||||
@@ -507,17 +720,22 @@ class PlaylistPanel(QWidget):
|
||||
self._lbl_progress.setText(f"{played} / {len(self._songs)} afspillet")
|
||||
for i, song in enumerate(self._songs):
|
||||
is_current = (i == self._current_idx and not self._song_ended)
|
||||
is_next = (self._song_ended and i == self._current_idx + 1) or \
|
||||
(self._current_idx == -1 and self._song_ended and i == 0)
|
||||
status = "playing" if is_current else "next" if is_next else self._statuses[i]
|
||||
status = "playing" if is_current else self._statuses[i]
|
||||
icon = self.STATUS_ICON.get(status, " ")
|
||||
dances = " / ".join(song.get("dances", [])) or "ingen dans tagget"
|
||||
text = f"{i+1:>2}. {song.get('title','—')}\n {song.get('artist','')} · {dances}"
|
||||
item = QListWidgetItem(f"{icon} {text}")
|
||||
|
||||
# Vis active_dance (override eller første dans) eller alle danse
|
||||
active = song.get("active_dance", "")
|
||||
if not active:
|
||||
dances = song.get("dances", [])
|
||||
active = dances[0] if dances else "ingen dans tagget"
|
||||
ws_tag = " 🎓" if song.get("is_workshop") else ""
|
||||
|
||||
text = (f"{i+1:>2}. {song.get('title','—')}{ws_tag}\n"
|
||||
f" {song.get('artist','')} · {active}")
|
||||
item = QListWidgetItem(f"{icon} {text}")
|
||||
item.setData(Qt.ItemDataRole.UserRole, i)
|
||||
color = self.STATUS_COLOR.get(status, "#5a6070")
|
||||
if status in ("playing", "next"):
|
||||
item.setForeground(QColor(color))
|
||||
if status == "playing":
|
||||
item.setForeground(QColor(self.STATUS_COLOR["playing"]))
|
||||
f = item.font(); f.setBold(True); item.setFont(f)
|
||||
elif status == "played":
|
||||
item.setForeground(QColor("#2ecc71"))
|
||||
|
||||
Reference in New Issue
Block a user