Med install

This commit is contained in:
2026-04-10 15:09:37 +02:00
parent e5a4711004
commit 0f54f6d908
8 changed files with 229 additions and 88 deletions

View File

@@ -169,10 +169,20 @@ class LibraryPanel(QWidget):
q = self._search.text().strip().lower()
for song in self._filtered:
dances = song.get("dances", [])
dance_str = " · " + " / ".join(dances) if dances else ""
dance_levels = song.get("dance_levels", [])
missing = song.get("file_missing", False)
# Byg dans-streng med niveau hvis tilgængeligt
dance_parts = []
for i, d in enumerate(dances):
lvl = dance_levels[i] if i < len(dance_levels) else ""
dance_parts.append(f"{d} / {lvl}" if lvl else d)
dance_str = " · " + " | ".join(dance_parts) if dance_parts else ""
line1 = ("" if missing else "") + song.get("title", "")
line2 = f" {song.get('artist','')} · {song.get('bpm',0)} BPM · {song.get('file_format','').upper()}{dance_str}"
bpm = song.get("bpm", 0)
bpm_str = f"{bpm} BPM" if bpm else "? BPM"
line2 = f" {song.get('artist','')} · {bpm_str} · {song.get('file_format','').upper()}{dance_str}"
item = QListWidgetItem(f"{line1}\n{line2}")
item.setData(Qt.ItemDataRole.UserRole, song)
if missing:
@@ -237,12 +247,16 @@ class LibraryPanel(QWidget):
self.done.emit(bpm)
self._bpm_worker = BpmWorker(path, song_id)
self._bpm_worker.done.connect(
lambda bpm: (
self._do_search(),
print(f"BPM analyseret: {bpm}")
)
)
def on_bpm_done(bpm):
# Opdater sangen i _all_songs listen direkte
for s in self._all_songs:
if s.get("id") == song_id:
s["bpm"] = int(round(bpm))
break
self._do_search()
self._bpm_worker.done.connect(on_bpm_done)
self._bpm_worker.start()
def _manage_libraries(self):

View File

@@ -439,9 +439,11 @@ class MainWindow(QMainWindow):
songs = []
for row in songs_raw:
with get_db() as conn:
dances = conn.execute(
"SELECT dance_name FROM song_dances "
"WHERE song_id=? ORDER BY dance_order",
dances_raw = conn.execute(
"SELECT sd.dance_name, dl.name as level_name "
"FROM song_dances sd "
"LEFT JOIN dance_levels dl ON dl.id = sd.level_id "
"WHERE sd.song_id=? ORDER BY sd.dance_order",
(row["id"],)
).fetchall()
songs.append({
@@ -454,7 +456,8 @@ class MainWindow(QMainWindow):
"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": [d["dance_name"] for d in dances_raw],
"dance_levels": [d["level_name"] or "" for d in dances_raw],
})
self._library_panel.load_songs(songs)
count = len(songs)
@@ -836,15 +839,13 @@ class MainWindow(QMainWindow):
self._vu.reset()
# Markér den afspillede sang
prev_idx = self._current_idx
self._playlist_panel.mark_played(prev_idx)
self._playlist_panel.mark_played(self._current_idx)
# Synkroniser event-status til den gemte navngivne liste
self._sync_event_status_to_playlist()
# Find ste afspilbare sang — fra 0 hvis ingen sang var i gang
search_from = max(0, prev_idx + 1)
ni = self._playlist_panel.next_playable_idx(search_from)
# Find første ikke-afspillede og ikke-skippede sang fra TOPPEN
ni = self._playlist_panel.next_playable_idx()
next_song = self._playlist_panel.get_song(ni) if ni is not None else None
if next_song:
self._current_idx = ni

View File

@@ -215,7 +215,7 @@ class PlaylistPanel(QWidget):
self._trigger_autosave()
# Find første afspilbare sang og udsend signal så afspilleren opdateres
ni = self.next_playable_idx(0)
ni = self.next_playable_idx()
if ni is not None:
self._current_idx = ni
self._refresh()
@@ -253,9 +253,9 @@ class PlaylistPanel(QWidget):
print(f"Event-state gendan fejl: {e}")
return False
def next_playable_idx(self, from_idx: int) -> int | None:
"""Find ste sang der ikke er 'skipped' eller 'played' fra from_idx."""
for i in range(from_idx, len(self._songs)):
def next_playable_idx(self) -> int | None:
"""Find første sang fra toppen der ikke er 'skipped' eller 'played'."""
for i in range(len(self._songs)):
if self._statuses[i] not in ("skipped", "played"):
return i
return None

View File

@@ -391,6 +391,7 @@ class TagEditorDialog(QDialog):
dances = [(r.get_name(), r.get_level_id())
for r in self._my_dance_rows if r.get_name()]
dance_ids = []
with get_db() as conn:
# Slet eksisterende danse og alternativer
old_dances = conn.execute(
@@ -400,28 +401,34 @@ class TagEditorDialog(QDialog):
conn.execute("DELETE FROM dance_alternatives WHERE song_dance_id=?", (od["id"],))
conn.execute("DELETE FROM song_dances WHERE song_id=?", (song_id,))
# Indsæt nye danse
dance_ids = []
# Indsæt nye danse og hent IDs
for i, (name, level_id) in enumerate(dances, start=1):
cur = conn.execute(
"INSERT INTO song_dances (song_id, dance_name, dance_order, level_id) VALUES (?,?,?,?)",
conn.execute(
"INSERT INTO song_dances (song_id, dance_name, dance_order, level_id) "
"VALUES (?,?,?,?)",
(song_id, name, i, level_id)
)
dance_ids.append(cur.lastrowid)
new_id = conn.execute(
"SELECT id FROM song_dances WHERE song_id=? AND dance_order=?",
(song_id, i)
).fetchone()["id"]
dance_ids.append(new_id)
register_dance_name(name)
# Indsæt alternativer (knyttet til første dans hvis flere)
if dance_ids and self._my_alt_rows:
first_dance_id = dance_ids[0]
for row in self._my_alt_rows:
name = row.get_name()
if name:
add_alternative(
first_dance_id, name,
level_id=row.get_level_id(),
note=row.get_note(),
source="local",
)
# Indsæt alternativer knyttet til første dans
if dance_ids and self._my_alt_rows:
first_dance_id = dance_ids[0]
for row in self._my_alt_rows:
name = row.get_name()
if name:
import uuid as _uuid
conn.execute("""
INSERT INTO dance_alternatives
(id, song_dance_id, alt_dance_name, level_id, note, source)
VALUES (?,?,?,?,?,'local')
""", (str(_uuid.uuid4()), first_dance_id,
name, row.get_level_id(), row.get_note()))
register_dance_name(name)
# Skriv til fil
if local_path and can_write_dances(local_path):