This commit is contained in:
2026-04-10 15:06:59 +02:00
parent 3031b7153b
commit e5a4711004
7806 changed files with 1918528 additions and 335 deletions

View File

@@ -115,38 +115,25 @@ class MainWindow(QMainWindow):
def _build_menu(self):
menubar = self.menuBar()
# Filer
# ── Filer ─────────────────────────────────────────────────────────────
file_menu = menubar.addMenu("Filer")
file_menu.addSeparator()
self._act_go_online = QAction("Gå online...", self)
self._act_go_online.setShortcut("Ctrl+L")
self._act_go_online.setToolTip("Log ind og synkroniser med server")
self._act_go_online.triggered.connect(self._go_online)
file_menu.addAction(self._act_go_online)
self._act_go_offline = QAction("Gå offline", self)
self._act_go_offline.setToolTip("Log ud og arbejd lokalt")
self._act_go_offline.triggered.connect(self._go_offline)
self._act_go_offline.setEnabled(False) # kun aktiv når man er online
self._act_go_offline.setEnabled(False)
file_menu.addAction(self._act_go_offline)
file_menu.addSeparator()
act_add_folder = QAction("Tilføj musikmappe...", self)
act_add_folder.setShortcut("Ctrl+O")
act_add_folder.triggered.connect(self._menu_add_folder)
file_menu.addAction(act_add_folder)
file_menu.addSeparator()
act_scan = QAction("Scan biblioteker", self)
act_scan.setShortcut("Ctrl+R")
act_scan.setToolTip("Gennemgå alle biblioteksmapper for nye og ændrede filer")
act_scan.triggered.connect(self.start_scan)
file_menu.addAction(act_scan)
self._act_scan = act_scan
act_settings = QAction("Indstillinger...", self)
act_settings.setShortcut("Ctrl+,")
act_settings.triggered.connect(self._open_settings)
file_menu.addAction(act_settings)
file_menu.addSeparator()
@@ -155,33 +142,14 @@ class MainWindow(QMainWindow):
act_quit.triggered.connect(self.close)
file_menu.addAction(act_quit)
# Danseliste
pl_menu = menubar.addMenu("Danseliste")
# ── Ingen Danseliste- eller Visning-menu ──────────────────────────────
# Ny/Gem/Hent ligger direkte i danseliste-panelet
# Tema-skift ligger i topbar-knappen
# Mapper og scan ligger i ⚙ Mapper dialogen
act_new_pl = QAction("Ny tom liste", self)
act_new_pl.setShortcut("Ctrl+N")
act_new_pl.triggered.connect(self._new_playlist)
pl_menu.addAction(act_new_pl)
act_manage = QAction("Gem / Indlæs / Importer...", self)
act_manage.setShortcut("Ctrl+M")
act_manage.triggered.connect(self._open_playlist_manager)
pl_menu.addAction(act_manage)
# Visning
view_menu = menubar.addMenu("Visning")
act_theme = QAction("Skift tema (lyst/mørkt)", self)
act_theme.setShortcut("Ctrl+T")
act_theme.triggered.connect(self._toggle_theme)
view_menu.addAction(act_theme)
view_menu.addSeparator()
act_settings = QAction("Indstillinger...", self)
act_settings.setShortcut("Ctrl+,")
act_settings.triggered.connect(self._open_settings)
view_menu.addAction(act_settings)
# Gem reference til scan-action (bruges stadig internt)
self._act_scan = QAction("Scan", self)
self._act_scan.triggered.connect(self.start_scan)
# ── Statuslinje ───────────────────────────────────────────────────────────
@@ -399,8 +367,10 @@ class MainWindow(QMainWindow):
init_db()
# Brug et Qt signal til thread-safe reload fra watcher-tråden
from PyQt6.QtCore import QMetaObject, Q_ARG
def on_file_change(event_type, path, song_id):
QTimer.singleShot(500, self._reload_library)
QTimer.singleShot(0, self._reload_library)
self._watcher = get_watcher(on_change=on_file_change)
self._watcher.start()
@@ -494,10 +464,16 @@ class MainWindow(QMainWindow):
def add_library_path(self, path: str):
try:
if not self._watcher:
self._set_status("Watcher ikke klar endnu — prøv igen om et øjeblik", 3000)
return
self._watcher.add_library(path)
self._set_status(f"Tilføjet: {path} — scanner...")
# Genindlæs bibliotekslisten og start scan
QTimer.singleShot(500, self._reload_library)
QTimer.singleShot(1000, self.start_scan)
except Exception as e:
self._set_status(f"Fejl: {e}")
self._set_status(f"Fejl ved tilføjelse: {e}")
def _open_settings(self):
dialog = SettingsDialog(parent=self)
@@ -860,10 +836,15 @@ class MainWindow(QMainWindow):
self._vu.reset()
# Markér den afspillede sang
self._playlist_panel.mark_played(self._current_idx)
prev_idx = self._current_idx
self._playlist_panel.mark_played(prev_idx)
# Find næste afspilbare sang — spring skippede og afspillede over
ni = self._playlist_panel.next_playable_idx(self._current_idx + 1)
# Synkroniser event-status til den gemte navngivne liste
self._sync_event_status_to_playlist()
# Find næ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)
next_song = self._playlist_panel.get_song(ni) if ni is not None else None
if next_song:
self._current_idx = ni
@@ -876,6 +857,29 @@ class MainWindow(QMainWindow):
self._lbl_dances.setText("")
self._set_status("Danselisten er afsluttet")
def _sync_event_status_to_playlist(self):
"""Gem event-fremgang i den aktive navngivne liste."""
try:
from local.local_db import get_db
songs = self._playlist_panel.get_songs()
statuses = self._playlist_panel.get_statuses()
with get_db() as conn:
# Find den aktive liste (ikke __aktiv__)
pl = conn.execute(
"SELECT id FROM playlists WHERE name != '__aktiv__' "
"ORDER BY created_at DESC LIMIT 1"
).fetchone()
if not pl:
return
# Opdater status for hver sang i listen
for i, (song, status) in enumerate(zip(songs, statuses)):
conn.execute("""
UPDATE playlist_songs SET status=?
WHERE playlist_id=? AND song_id=?
""", (status, pl["id"], song.get("id")))
except Exception as e:
print(f"Event-status sync fejl: {e}")
def _on_state_changed(self, state: str):
if state == "playing":
self._btn_play.setText("")