diff --git a/main.py b/main.py
index a885009..fc93c75 100755
--- a/main.py
+++ b/main.py
@@ -4287,11 +4287,11 @@ class MainWindow(QMainWindow):
self._btn_shortcuts.clicked.connect(self._show_shortcuts)
# Right-side layout (video + controls)
+ # Profile selector and the ? shortcuts button live in the menu-bar
+ # corner widget (built in _build_menubar); top_bar keeps only the
+ # slim filename header above the video.
top_bar = QHBoxLayout()
top_bar.addWidget(self._lbl_file, stretch=1)
- top_bar.addWidget(QLabel("Profile:"))
- top_bar.addWidget(self._cmb_profile)
- top_bar.addWidget(self._btn_shortcuts)
# Row 1 — transport + export actions
transport_row = QHBoxLayout()
@@ -4425,6 +4425,10 @@ class MainWindow(QMainWindow):
self._scan_panel.loaded.connect(self._on_scan_panel_loaded)
self._sld_threshold.valueChanged.connect(self._on_threshold_changed)
+ # Menu bar — wires to the existing handler methods above. Built here,
+ # after _scan_panel and every referenced widget/button exist.
+ self._build_menubar()
+
# Root: horizontal splitter
splitter = QSplitter(Qt.Orientation.Horizontal)
splitter.addWidget(left)
@@ -4494,6 +4498,81 @@ class MainWindow(QMainWindow):
# Defer the changelog modal so the window paints/interacts first.
QTimer.singleShot(120, self._show_changelog)
+ # ── Menu bar ─────────────────────────────────────────────
+
+ def _build_menubar(self) -> None:
+ from PyQt6.QtGui import QAction
+ mb = self.menuBar()
+
+ # File
+ m_file = mb.addMenu("&File")
+ m_file.addAction("Open Files…", self._on_open_files)
+ m_file.addAction("Set export folder…", self._pick_folder)
+ m_file.addSeparator()
+ m_file.addAction("Quit", self.close)
+
+ # Edit
+ m_edit = mb.addMenu("&Edit")
+ self._act_undo = m_edit.addAction("Undo scan edit", self._scan_panel.undo)
+ self._act_undo.setShortcut("Ctrl+Z")
+ m_edit.addSeparator()
+ m_subs = m_edit.addMenu("Subprofiles")
+ m_subs.addAction("Add…", self._new_subprofile)
+ self._menu_subprofiles_remove = m_subs.addMenu("Remove")
+ self._rebuild_remove_subprofile_menu() # built in Task 4.x
+
+ # Scan
+ m_scan = mb.addMenu("&Scan")
+ m_scan.addAction("Scan current", self._start_scan)
+ m_scan.addAction("Auto-export", self._auto_export)
+ m_scan.addSeparator()
+ m_scan.addAction("Scan All…", self._start_scan_all)
+ m_scan.addAction("Train classifier…", self._open_train_dialog)
+
+ # View
+ m_view = mb.addMenu("&View")
+ self._act_review = m_view.addAction("Review mode")
+ self._act_review.setCheckable(True)
+ self._act_review.toggled.connect(self._btn_scan_mode.setChecked)
+ m_view.addAction("Subcategory markers…", self._show_subcat_menu)
+ m_view.addSeparator()
+ self._act_hide_exported = m_view.addAction("Hide exported")
+ self._act_hide_exported.setCheckable(True)
+ self._act_hide_exported.toggled.connect(self._chk_hide_exported.setChecked)
+ self._chk_hide_exported.toggled.connect(self._act_hide_exported.setChecked)
+ self._act_show_hidden = m_view.addAction("Show hidden")
+ self._act_show_hidden.setCheckable(True)
+ self._act_show_hidden.toggled.connect(self._btn_show_hidden.setChecked)
+ self._btn_show_hidden.toggled.connect(self._act_show_hidden.setChecked)
+
+ # Help
+ m_help = mb.addMenu("&Help")
+ m_help.addAction("Keyboard shortcuts", self._show_shortcuts).setShortcut("F1")
+ m_help.addAction("What's new", self._show_changelog)
+ m_help.addAction("About", self._show_about) # tiny method, Task 1.3
+
+ # Profile selector + ? help button live in the top-right corner.
+ from PyQt6.QtWidgets import QWidget, QHBoxLayout, QLabel
+ corner = QWidget()
+ ch = QHBoxLayout(corner)
+ ch.setContentsMargins(0, 0, 6, 0)
+ ch.addWidget(QLabel("Profile:"))
+ ch.addWidget(self._cmb_profile)
+ ch.addWidget(self._btn_shortcuts)
+ mb.setCornerWidget(corner, Qt.Corner.TopRightCorner)
+
+ def _show_about(self) -> None:
+ QMessageBox.about(self, "About 8-cut",
+ f"8-cut v{self.APP_VERSION}
"
+ "8-second clips for foley datasets.")
+
+ def _rebuild_remove_subprofile_menu(self) -> None:
+ self._menu_subprofiles_remove.clear()
+ for name in self._subprofiles:
+ self._menu_subprofiles_remove.addAction(
+ name, lambda _=False, n=name: self._remove_subprofile(n))
+ self._menu_subprofiles_remove.setEnabled(bool(self._subprofiles))
+
# ── Changelog ────────────────────────────────────────────
APP_VERSION = "1.0"