feat: wire playlist and DB into MainWindow

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-06 12:53:41 +02:00
parent 75fd43577e
commit ccdb50c6a4
+42 -29
View File
@@ -334,8 +334,10 @@ class MainWindow(QMainWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.setWindowTitle("8-cut") self.setWindowTitle("8-cut")
self.resize(900, 680) self.resize(1100, 680)
self.setAcceptDrops(True)
# Services
self._db = ProcessedDB()
# State # State
self._file_path: str = "" self._file_path: str = ""
@@ -344,12 +346,15 @@ class MainWindow(QMainWindow):
self._export_worker: ExportWorker | None = None self._export_worker: ExportWorker | None = None
# Widgets # Widgets
self._playlist = PlaylistWidget()
self._playlist.file_selected.connect(self._load_file)
self._mpv = MpvWidget() self._mpv = MpvWidget()
self._mpv.file_loaded.connect(self._after_load) self._mpv.file_loaded.connect(self._after_load)
self._timeline = TimelineWidget() self._timeline = TimelineWidget()
self._timeline.cursor_changed.connect(self._on_cursor_changed) self._timeline.cursor_changed.connect(self._on_cursor_changed)
self._lbl_file = QLabel("Drop a video file here") self._lbl_file = QLabel("Drop files onto the queue →")
self._lbl_file.setAlignment(Qt.AlignmentFlag.AlignCenter) self._lbl_file.setAlignment(Qt.AlignmentFlag.AlignCenter)
self._lbl_file.setStyleSheet("color: #aaa; padding: 6px;") self._lbl_file.setStyleSheet("color: #aaa; padding: 6px;")
@@ -381,7 +386,7 @@ class MainWindow(QMainWindow):
self._btn_export.setEnabled(False) self._btn_export.setEnabled(False)
self._btn_export.clicked.connect(self._on_export) self._btn_export.clicked.connect(self._on_export)
# Layout # Right-side layout (video + controls)
top_bar = QHBoxLayout() top_bar = QHBoxLayout()
top_bar.addWidget(self._lbl_file, stretch=1) top_bar.addWidget(self._lbl_file, stretch=1)
@@ -401,38 +406,40 @@ class MainWindow(QMainWindow):
export_row.addWidget(self._lbl_next) export_row.addWidget(self._lbl_next)
export_row.addWidget(self._btn_export) export_row.addWidget(self._btn_export)
root = QVBoxLayout() right = QWidget()
root.addLayout(top_bar) right_layout = QVBoxLayout(right)
root.addWidget(self._mpv, stretch=1) right_layout.setContentsMargins(0, 0, 0, 0)
root.addWidget(self._timeline) right_layout.addLayout(top_bar)
root.addLayout(controls) right_layout.addWidget(self._mpv, stretch=1)
root.addLayout(export_row) right_layout.addWidget(self._timeline)
right_layout.addLayout(controls)
right_layout.addLayout(export_row)
container = QWidget() # Left: queue label + playlist
container.setLayout(root) queue_label = QLabel("Queue")
self.setCentralWidget(container) queue_label.setStyleSheet("color: #aaa; padding: 4px;")
left = QWidget()
left_layout = QVBoxLayout(left)
left_layout.setContentsMargins(4, 4, 4, 4)
left_layout.addWidget(queue_label)
left_layout.addWidget(self._playlist)
# Root: horizontal splitter
splitter = QSplitter(Qt.Orientation.Horizontal)
splitter.addWidget(left)
splitter.addWidget(right)
splitter.setSizes([200, 900])
splitter.setCollapsible(0, False)
splitter.setCollapsible(1, False)
self.setCentralWidget(splitter)
self.setStatusBar(QStatusBar()) self.setStatusBar(QStatusBar())
# --- Drag & Drop ---
def dragEnterEvent(self, event: QDragEnterEvent):
if event.mimeData().hasUrls():
event.acceptProposedAction()
def dropEvent(self, event: QDropEvent):
urls = event.mimeData().urls()
if urls:
path = urls[0].toLocalFile()
self._load_file(path)
def _load_file(self, path: str): def _load_file(self, path: str):
if not os.path.isfile(path):
self.statusBar().showMessage(f"Not a file: {os.path.basename(path)}")
return
self._file_path = path self._file_path = path
self._lbl_file.setText(os.path.basename(path)) self._lbl_file.setText(os.path.basename(path))
self._mpv.load(path) self._mpv.load(path)
# _after_load is triggered by MpvWidget.file_loaded signal (connected in __init__) # _after_load triggered by MpvWidget.file_loaded signal
def _after_load(self): def _after_load(self):
dur = self._mpv.get_duration() dur = self._mpv.get_duration()
@@ -444,6 +451,10 @@ class MainWindow(QMainWindow):
self._btn_pause.setEnabled(True) self._btn_pause.setEnabled(True)
self._btn_export.setEnabled(True) self._btn_export.setEnabled(True)
match = self._db.find_similar(os.path.basename(self._file_path))
if match:
self.statusBar().showMessage(f"⚠ Similar to already processed: {match}")
# --- Playback --- # --- Playback ---
def _on_cursor_changed(self, t: float): def _on_cursor_changed(self, t: float):
@@ -502,10 +513,12 @@ class MainWindow(QMainWindow):
self._export_worker.start() self._export_worker.start()
def _on_export_done(self, path: str): def _on_export_done(self, path: str):
self._db.add(os.path.basename(self._file_path))
self._export_counter += 1 self._export_counter += 1
self._update_next_label() self._update_next_label()
self._btn_export.setEnabled(True) self._btn_export.setEnabled(True)
self.statusBar().showMessage(f"Exported: {os.path.basename(path)}") self.statusBar().showMessage(f"Exported: {os.path.basename(path)}")
self._playlist.advance()
def _on_export_error(self, msg: str): def _on_export_error(self, msg: str):
self._btn_export.setEnabled(True) self._btn_export.setEnabled(True)