Revert "feat: label history, overwrite mode, crop overlay, UX improvements"
This reverts commit ff0cd00309.
This commit is contained in:
@@ -64,7 +64,7 @@ def build_ffmpeg_command(
|
|||||||
# if(lt(iw,ih),...) → portrait output: fix width; landscape: fix height.
|
# if(lt(iw,ih),...) → portrait output: fix width; landscape: fix height.
|
||||||
# -2 keeps aspect ratio with even-pixel rounding (libx264 requirement).
|
# -2 keeps aspect ratio with even-pixel rounding (libx264 requirement).
|
||||||
filters.append(
|
filters.append(
|
||||||
f"scale='if(lt(iw,ih),{short_side},-2)':'if(lt(iw,ih),-2,{short_side})':flags=lanczos"
|
f"scale='if(lt(iw,ih),{short_side},-2)':'if(lt(iw,ih),-2,{short_side})'"
|
||||||
)
|
)
|
||||||
if filters:
|
if filters:
|
||||||
cmd += ["-vf", ",".join(filters)]
|
cmd += ["-vf", ",".join(filters)]
|
||||||
@@ -73,7 +73,7 @@ def build_ffmpeg_command(
|
|||||||
cmd += [
|
cmd += [
|
||||||
"-an",
|
"-an",
|
||||||
"-c:v", "libwebp",
|
"-c:v", "libwebp",
|
||||||
"-quality", "92",
|
"-quality", "85",
|
||||||
"-compression_level", "1",
|
"-compression_level", "1",
|
||||||
os.path.join(output_path, "frame_%04d.webp"),
|
os.path.join(output_path, "frame_%04d.webp"),
|
||||||
]
|
]
|
||||||
@@ -220,24 +220,6 @@ class ProcessedDB:
|
|||||||
)
|
)
|
||||||
self._con.commit()
|
self._con.commit()
|
||||||
|
|
||||||
def get_labels(self) -> list[str]:
|
|
||||||
"""Return distinct non-empty labels ordered by most recently used."""
|
|
||||||
if not self._enabled:
|
|
||||||
return []
|
|
||||||
rows = self._con.execute(
|
|
||||||
"SELECT DISTINCT label FROM processed"
|
|
||||||
" WHERE label != '' ORDER BY processed_at DESC"
|
|
||||||
).fetchall()
|
|
||||||
# Deduplicate while preserving order (DISTINCT on processed_at DESC
|
|
||||||
# may return duplicates if the same label was used multiple times).
|
|
||||||
seen: set[str] = set()
|
|
||||||
result = []
|
|
||||||
for (lbl,) in rows:
|
|
||||||
if lbl not in seen:
|
|
||||||
seen.add(lbl)
|
|
||||||
result.append(lbl)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def delete_by_output_path(self, output_path: str) -> None:
|
def delete_by_output_path(self, output_path: str) -> None:
|
||||||
if not self._enabled:
|
if not self._enabled:
|
||||||
return
|
return
|
||||||
@@ -347,7 +329,6 @@ class ExportWorker(QThread):
|
|||||||
class TimelineWidget(QWidget):
|
class TimelineWidget(QWidget):
|
||||||
cursor_changed = pyqtSignal(float) # emits position in seconds
|
cursor_changed = pyqtSignal(float) # emits position in seconds
|
||||||
marker_delete_requested = pyqtSignal(str) # emits output_path
|
marker_delete_requested = pyqtSignal(str) # emits output_path
|
||||||
marker_clicked = pyqtSignal(float, str) # emits (start_time, output_path)
|
|
||||||
|
|
||||||
_RULER_H = 22 # pixels reserved for the time ruler
|
_RULER_H = 22 # pixels reserved for the time ruler
|
||||||
_HANDLE_H = 8 # height of the playhead triangle
|
_HANDLE_H = 8 # height of the playhead triangle
|
||||||
@@ -516,16 +497,6 @@ class TimelineWidget(QWidget):
|
|||||||
p.end()
|
p.end()
|
||||||
|
|
||||||
def mousePressEvent(self, event):
|
def mousePressEvent(self, event):
|
||||||
from PyQt6.QtCore import Qt as _Qt
|
|
||||||
if event.button() == _Qt.MouseButton.LeftButton and self._hover_cache:
|
|
||||||
x = event.position().x()
|
|
||||||
w = self.width()
|
|
||||||
for (frac, output_path) in self._hover_cache:
|
|
||||||
if abs(x - frac * w) <= 6:
|
|
||||||
t = frac * self._duration
|
|
||||||
self._seek(x)
|
|
||||||
self.marker_clicked.emit(t, output_path)
|
|
||||||
return
|
|
||||||
self._seek(event.position().x())
|
self._seek(event.position().x())
|
||||||
|
|
||||||
def mouseMoveEvent(self, event):
|
def mouseMoveEvent(self, event):
|
||||||
@@ -595,8 +566,6 @@ class MpvWidget(QWidget):
|
|||||||
self.setFocusPolicy(Qt.FocusPolicy.NoFocus)
|
self.setFocusPolicy(Qt.FocusPolicy.NoFocus)
|
||||||
self._frame: "QImage | None" = None
|
self._frame: "QImage | None" = None
|
||||||
self._render_ctx = None
|
self._render_ctx = None
|
||||||
self._video_w: int = 0
|
|
||||||
self._video_h: int = 0
|
|
||||||
self._fbo = None
|
self._fbo = None
|
||||||
self._needs_render = False # set True by mpv update_cb (any thread)
|
self._needs_render = False # set True by mpv update_cb (any thread)
|
||||||
|
|
||||||
@@ -641,27 +610,12 @@ class MpvWidget(QWidget):
|
|||||||
self._render_timer.timeout.connect(self._poll_render)
|
self._render_timer.timeout.connect(self._poll_render)
|
||||||
self._render_timer.start()
|
self._render_timer.start()
|
||||||
|
|
||||||
self._do_file_loaded.connect(self._on_file_loaded_qt)
|
self._do_file_loaded.connect(self.file_loaded)
|
||||||
self._overlay_ratio: tuple[int, int] | None = None # (num, den) or None
|
|
||||||
self._overlay_crop_center: float = 0.5
|
|
||||||
self._overlay_fracs: "tuple[float, float] | None" = None # (left_frac, right_frac)
|
|
||||||
|
|
||||||
@self._player.event_callback("file-loaded")
|
@self._player.event_callback("file-loaded")
|
||||||
def _on_file_loaded(event):
|
def _on_file_loaded(event):
|
||||||
self._do_file_loaded.emit()
|
self._do_file_loaded.emit()
|
||||||
|
|
||||||
def _on_file_loaded_qt(self) -> None:
|
|
||||||
self._video_w = self._player.width or 0
|
|
||||||
self._video_h = self._player.height or 0
|
|
||||||
self._overlay_fracs = None # recompute with new dimensions
|
|
||||||
self.file_loaded.emit()
|
|
||||||
|
|
||||||
def set_crop_overlay(self, ratio: "tuple[int,int] | None", crop_center: float) -> None:
|
|
||||||
self._overlay_ratio = ratio
|
|
||||||
self._overlay_crop_center = crop_center
|
|
||||||
self._overlay_fracs: "tuple[float,float] | None" = None # invalidate cache
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def _on_mpv_update(self):
|
def _on_mpv_update(self):
|
||||||
# Called from mpv's C thread — only set a flag, no Qt calls here.
|
# Called from mpv's C thread — only set a flag, no Qt calls here.
|
||||||
self._needs_render = True
|
self._needs_render = True
|
||||||
@@ -698,30 +652,6 @@ class MpvWidget(QWidget):
|
|||||||
p.drawImage(self.rect(), self._frame)
|
p.drawImage(self.rect(), self._frame)
|
||||||
else:
|
else:
|
||||||
p.fillRect(self.rect(), QColor(0, 0, 0))
|
p.fillRect(self.rect(), QColor(0, 0, 0))
|
||||||
|
|
||||||
if self._overlay_ratio is not None and self._player.pause:
|
|
||||||
if self._overlay_fracs is None:
|
|
||||||
vw, vh = self._video_w, self._video_h
|
|
||||||
if vw > 0 and vh > 0:
|
|
||||||
num, den = self._overlay_ratio
|
|
||||||
crop_w_frac = min((vh * num / den) / vw, 1.0)
|
|
||||||
half = crop_w_frac / 2.0
|
|
||||||
center = self._overlay_crop_center
|
|
||||||
self._overlay_fracs = (
|
|
||||||
max(0.0, center - half),
|
|
||||||
min(1.0, center + half),
|
|
||||||
)
|
|
||||||
if self._overlay_fracs is not None:
|
|
||||||
left_frac, right_frac = self._overlay_fracs
|
|
||||||
ww, wh = self.width(), self.height()
|
|
||||||
left_px = int(left_frac * ww)
|
|
||||||
right_px = int(right_frac * ww)
|
|
||||||
cut_color = QColor(180, 0, 0, 140)
|
|
||||||
if left_px > 0:
|
|
||||||
p.fillRect(0, 0, left_px, wh, cut_color)
|
|
||||||
if right_px < ww:
|
|
||||||
p.fillRect(right_px, 0, ww - right_px, wh, cut_color)
|
|
||||||
|
|
||||||
p.end()
|
p.end()
|
||||||
|
|
||||||
def mousePressEvent(self, event):
|
def mousePressEvent(self, event):
|
||||||
@@ -732,17 +662,12 @@ class MpvWidget(QWidget):
|
|||||||
def load(self, path: str): self._player.play(path)
|
def load(self, path: str): self._player.play(path)
|
||||||
|
|
||||||
def seek(self, t: float):
|
def seek(self, t: float):
|
||||||
if self._player.duration is None:
|
self._player.pause = True
|
||||||
return
|
|
||||||
try:
|
|
||||||
self._player.seek(t, "absolute")
|
self._player.seek(t, "absolute")
|
||||||
except SystemError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def play_loop(self, a: float, b: float):
|
def play_loop(self, a: float, b: float):
|
||||||
self._player["ab-loop-a"] = a
|
self._player["ab-loop-a"] = a
|
||||||
self._player["ab-loop-b"] = min(b, self._player.duration or b)
|
self._player["ab-loop-b"] = min(b, self._player.duration or b)
|
||||||
self._player.seek(a, "absolute")
|
|
||||||
self._player.pause = False
|
self._player.pause = False
|
||||||
|
|
||||||
def stop_loop(self):
|
def stop_loop(self):
|
||||||
@@ -755,7 +680,7 @@ class MpvWidget(QWidget):
|
|||||||
return d if d else 0.0
|
return d if d else 0.0
|
||||||
|
|
||||||
def get_video_size(self) -> tuple[int, int]:
|
def get_video_size(self) -> tuple[int, int]:
|
||||||
return (self._video_w, self._video_h)
|
return (self._player.width or 0, self._player.height or 0)
|
||||||
|
|
||||||
def get_fps(self) -> float:
|
def get_fps(self) -> float:
|
||||||
return self._player.container_fps or 25.0
|
return self._player.container_fps or 25.0
|
||||||
@@ -878,18 +803,6 @@ class PlaylistWidget(QListWidget):
|
|||||||
if was_empty and self._paths:
|
if was_empty and self._paths:
|
||||||
self._select(0)
|
self._select(0)
|
||||||
|
|
||||||
def mark_done(self, path: str) -> None:
|
|
||||||
"""Gray out and prefix ✓ on the queue item for path."""
|
|
||||||
if path not in self._path_set:
|
|
||||||
return
|
|
||||||
row = self._paths.index(path)
|
|
||||||
item = self.item(row)
|
|
||||||
if item is None:
|
|
||||||
return
|
|
||||||
name = os.path.basename(path)
|
|
||||||
item.setText(f"✓ {name}")
|
|
||||||
item.setForeground(QColor(100, 180, 100))
|
|
||||||
|
|
||||||
def advance(self) -> None:
|
def advance(self) -> None:
|
||||||
"""Move to next item in queue. Does nothing if at end or nothing selected."""
|
"""Move to next item in queue. Does nothing if at end or nothing selected."""
|
||||||
row = self.currentRow()
|
row = self.currentRow()
|
||||||
@@ -903,24 +816,13 @@ class PlaylistWidget(QListWidget):
|
|||||||
def _select(self, row: int) -> None:
|
def _select(self, row: int) -> None:
|
||||||
prev = self.currentRow()
|
prev = self.currentRow()
|
||||||
self.setCurrentRow(row)
|
self.setCurrentRow(row)
|
||||||
|
# Only update the two items that actually changed label.
|
||||||
if prev >= 0 and prev != row and self.item(prev):
|
if prev >= 0 and prev != row and self.item(prev):
|
||||||
self._refresh_item_text(prev)
|
self.item(prev).setText(os.path.basename(self._paths[prev]))
|
||||||
if self.item(row):
|
if self.item(row):
|
||||||
item = self.item(row)
|
self.item(row).setText(f"▶ {os.path.basename(self._paths[row])}")
|
||||||
prefix = "✓ " if item.foreground().color() == QColor(100, 180, 100) else ""
|
|
||||||
item.setText(f"▶ {prefix}{os.path.basename(self._paths[row])}")
|
|
||||||
self.file_selected.emit(self._paths[row])
|
self.file_selected.emit(self._paths[row])
|
||||||
|
|
||||||
def _refresh_item_text(self, row: int) -> None:
|
|
||||||
item = self.item(row)
|
|
||||||
if item is None:
|
|
||||||
return
|
|
||||||
name = os.path.basename(self._paths[row])
|
|
||||||
if item.foreground().color() == QColor(100, 180, 100):
|
|
||||||
item.setText(f"✓ {name}")
|
|
||||||
else:
|
|
||||||
item.setText(name)
|
|
||||||
|
|
||||||
def _on_item_clicked(self, item: QListWidgetItem) -> None:
|
def _on_item_clicked(self, item: QListWidgetItem) -> None:
|
||||||
self._select(self.row(item))
|
self._select(self.row(item))
|
||||||
|
|
||||||
@@ -1114,7 +1016,6 @@ class MainWindow(QMainWindow):
|
|||||||
self._export_counter: int = 1
|
self._export_counter: int = 1
|
||||||
self._export_worker: ExportWorker | None = None
|
self._export_worker: ExportWorker | None = None
|
||||||
self._last_export_path: str = ""
|
self._last_export_path: str = ""
|
||||||
self._overwrite_path: str = "" # set when a marker is selected for re-export
|
|
||||||
self._mask_worker: MaskWorker | None = None
|
self._mask_worker: MaskWorker | None = None
|
||||||
self._db_worker: _DBWorker | None = None
|
self._db_worker: _DBWorker | None = None
|
||||||
self._fps: float = 25.0 # cached on file load via get_fps()
|
self._fps: float = 25.0 # cached on file load via get_fps()
|
||||||
@@ -1129,7 +1030,6 @@ class MainWindow(QMainWindow):
|
|||||||
self._timeline.setFixedHeight(160)
|
self._timeline.setFixedHeight(160)
|
||||||
self._timeline.cursor_changed.connect(self._on_cursor_changed)
|
self._timeline.cursor_changed.connect(self._on_cursor_changed)
|
||||||
self._timeline.marker_delete_requested.connect(self._on_delete_marker)
|
self._timeline.marker_delete_requested.connect(self._on_delete_marker)
|
||||||
self._timeline.marker_clicked.connect(self._on_marker_clicked)
|
|
||||||
|
|
||||||
self._lbl_file = QLabel("Drop files onto the queue →")
|
self._lbl_file = QLabel("Drop files onto the queue →")
|
||||||
self._lbl_file.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
self._lbl_file.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
@@ -1189,15 +1089,12 @@ class MainWindow(QMainWindow):
|
|||||||
)
|
)
|
||||||
self._cmb_format.currentTextChanged.connect(self._update_next_label)
|
self._cmb_format.currentTextChanged.connect(self._update_next_label)
|
||||||
|
|
||||||
self._txt_label = QComboBox()
|
self._txt_label = QLineEdit()
|
||||||
self._txt_label.setEditable(True)
|
self._txt_label.setPlaceholderText("Sound label (e.g. dog barking)")
|
||||||
self._txt_label.setInsertPolicy(QComboBox.InsertPolicy.NoInsert)
|
self._txt_label.setFixedWidth(200)
|
||||||
self._txt_label.lineEdit().setPlaceholderText("Sound label (e.g. dog barking)")
|
|
||||||
self._txt_label.setFixedWidth(220)
|
|
||||||
self._txt_label.addItems(self._db.get_labels())
|
|
||||||
saved_label = self._settings.value("sound_label", "")
|
saved_label = self._settings.value("sound_label", "")
|
||||||
self._txt_label.setCurrentText(saved_label)
|
self._txt_label.setText(saved_label)
|
||||||
self._txt_label.currentTextChanged.connect(
|
self._txt_label.textChanged.connect(
|
||||||
lambda v: self._settings.setValue("sound_label", v)
|
lambda v: self._settings.setValue("sound_label", v)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1316,8 +1213,6 @@ class MainWindow(QMainWindow):
|
|||||||
self.setCentralWidget(splitter)
|
self.setCentralWidget(splitter)
|
||||||
self.setStatusBar(QStatusBar())
|
self.setStatusBar(QStatusBar())
|
||||||
self._crop_bar.setVisible(saved_ratio != "Off")
|
self._crop_bar.setVisible(saved_ratio != "Off")
|
||||||
if saved_ratio != "Off":
|
|
||||||
self._mpv.set_crop_overlay(_RATIOS[saved_ratio], self._crop_center)
|
|
||||||
|
|
||||||
# Application-wide shortcuts — fire regardless of which widget has focus.
|
# Application-wide shortcuts — fire regardless of which widget has focus.
|
||||||
ctx = Qt.ShortcutContext.ApplicationShortcut
|
ctx = Qt.ShortcutContext.ApplicationShortcut
|
||||||
@@ -1399,21 +1294,11 @@ class MainWindow(QMainWindow):
|
|||||||
f"Deleted marker: {os.path.basename(output_path)}", 4000
|
f"Deleted marker: {os.path.basename(output_path)}", 4000
|
||||||
)
|
)
|
||||||
|
|
||||||
def _on_marker_clicked(self, start_time: float, output_path: str) -> None:
|
|
||||||
self._overwrite_path = output_path
|
|
||||||
self._lbl_next.setText(f"↺ {os.path.basename(output_path)}")
|
|
||||||
self.statusBar().showMessage(
|
|
||||||
f"Overwrite mode: {os.path.basename(output_path)} — export to replace", 5000
|
|
||||||
)
|
|
||||||
|
|
||||||
def _on_portrait_ratio_changed(self, text: str) -> None:
|
def _on_portrait_ratio_changed(self, text: str) -> None:
|
||||||
ratio = None if text == "Off" else text
|
ratio = None if text == "Off" else text
|
||||||
self._crop_bar.set_portrait_ratio(ratio)
|
self._crop_bar.set_portrait_ratio(ratio)
|
||||||
self._crop_bar.setVisible(ratio is not None)
|
self._crop_bar.setVisible(ratio is not None)
|
||||||
self._settings.setValue("portrait_ratio", text)
|
self._settings.setValue("portrait_ratio", text)
|
||||||
self._mpv.set_crop_overlay(
|
|
||||||
_RATIOS[ratio] if ratio else None, self._crop_center
|
|
||||||
)
|
|
||||||
|
|
||||||
def _on_crop_click(self, frac: float) -> None:
|
def _on_crop_click(self, frac: float) -> None:
|
||||||
ratio = self._cmb_portrait.currentText()
|
ratio = self._cmb_portrait.currentText()
|
||||||
@@ -1422,19 +1307,12 @@ class MainWindow(QMainWindow):
|
|||||||
self._crop_center = max(0.0, min(1.0, frac))
|
self._crop_center = max(0.0, min(1.0, frac))
|
||||||
self._settings.setValue("crop_center", str(self._crop_center))
|
self._settings.setValue("crop_center", str(self._crop_center))
|
||||||
self._crop_bar.set_crop_center(self._crop_center)
|
self._crop_bar.set_crop_center(self._crop_center)
|
||||||
self._mpv.set_crop_overlay(_RATIOS[ratio], self._crop_center)
|
|
||||||
|
|
||||||
# --- Playback ---
|
# --- Playback ---
|
||||||
|
|
||||||
def _on_cursor_changed(self, t: float):
|
def _on_cursor_changed(self, t: float):
|
||||||
self._cursor = t
|
self._cursor = t
|
||||||
self._lbl_cursor.setText(f"cursor: {format_time(t)}")
|
self._lbl_cursor.setText(f"cursor: {format_time(t)}")
|
||||||
if self._overwrite_path:
|
|
||||||
self._overwrite_path = ""
|
|
||||||
self._update_next_label()
|
|
||||||
if self._mpv.is_playing():
|
|
||||||
self._mpv.play_loop(t, t + 8.0)
|
|
||||||
else:
|
|
||||||
self._mpv.seek(t)
|
self._mpv.seek(t)
|
||||||
|
|
||||||
def _toggle_play(self):
|
def _toggle_play(self):
|
||||||
@@ -1492,16 +1370,10 @@ class MainWindow(QMainWindow):
|
|||||||
def _update_next_label(self):
|
def _update_next_label(self):
|
||||||
folder = self._txt_folder.text()
|
folder = self._txt_folder.text()
|
||||||
name = self._txt_name.text() or "clip"
|
name = self._txt_name.text() or "clip"
|
||||||
is_seq = self._cmb_format.currentText() == "WebP sequence"
|
if self._cmb_format.currentText() == "WebP sequence":
|
||||||
# Advance past any files/dirs that already exist on disk.
|
|
||||||
while True:
|
|
||||||
if is_seq:
|
|
||||||
path = build_sequence_dir(folder, name, self._export_counter)
|
path = build_sequence_dir(folder, name, self._export_counter)
|
||||||
else:
|
else:
|
||||||
path = build_export_path(folder, name, self._export_counter)
|
path = build_export_path(folder, name, self._export_counter)
|
||||||
if not os.path.exists(path):
|
|
||||||
break
|
|
||||||
self._export_counter += 1
|
|
||||||
self._lbl_next.setText(f"→ {os.path.basename(path)}")
|
self._lbl_next.setText(f"→ {os.path.basename(path)}")
|
||||||
|
|
||||||
def _on_export(self):
|
def _on_export(self):
|
||||||
@@ -1514,11 +1386,6 @@ class MainWindow(QMainWindow):
|
|||||||
fmt = self._cmb_format.currentText()
|
fmt = self._cmb_format.currentText()
|
||||||
image_sequence = fmt == "WebP sequence"
|
image_sequence = fmt == "WebP sequence"
|
||||||
folder = self._txt_folder.text()
|
folder = self._txt_folder.text()
|
||||||
os.makedirs(folder, exist_ok=True)
|
|
||||||
if self._overwrite_path:
|
|
||||||
output = self._overwrite_path
|
|
||||||
self._overwrite_path = ""
|
|
||||||
else:
|
|
||||||
name = self._txt_name.text() or "clip"
|
name = self._txt_name.text() or "clip"
|
||||||
if image_sequence:
|
if image_sequence:
|
||||||
output = build_sequence_dir(folder, name, self._export_counter)
|
output = build_sequence_dir(folder, name, self._export_counter)
|
||||||
@@ -1555,7 +1422,7 @@ 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):
|
||||||
label = self._txt_label.currentText().strip()
|
label = self._txt_label.text().strip()
|
||||||
category = self._cmb_category.currentText()
|
category = self._cmb_category.currentText()
|
||||||
self._db.add(
|
self._db.add(
|
||||||
os.path.basename(self._file_path),
|
os.path.basename(self._file_path),
|
||||||
@@ -1574,14 +1441,6 @@ class MainWindow(QMainWindow):
|
|||||||
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._refresh_markers()
|
self._refresh_markers()
|
||||||
self._playlist.mark_done(self._file_path)
|
|
||||||
# Refresh label history so the new label is immediately selectable.
|
|
||||||
current = self._txt_label.currentText()
|
|
||||||
self._txt_label.blockSignals(True)
|
|
||||||
self._txt_label.clear()
|
|
||||||
self._txt_label.addItems(self._db.get_labels())
|
|
||||||
self._txt_label.setCurrentText(current)
|
|
||||||
self._txt_label.blockSignals(False)
|
|
||||||
self._playlist.advance()
|
self._playlist.advance()
|
||||||
|
|
||||||
def _on_export_error(self, msg: str):
|
def _on_export_error(self, msg: str):
|
||||||
@@ -1609,9 +1468,6 @@ class MainWindow(QMainWindow):
|
|||||||
]
|
]
|
||||||
if paths:
|
if paths:
|
||||||
self._playlist.add_files(paths)
|
self._playlist.add_files(paths)
|
||||||
for p in paths:
|
|
||||||
if self._db.get_markers(os.path.basename(p)):
|
|
||||||
self._playlist.mark_done(p)
|
|
||||||
|
|
||||||
def _on_venv_installed(self) -> None:
|
def _on_venv_installed(self) -> None:
|
||||||
self._btn_masks.setEnabled(True)
|
self._btn_masks.setEnabled(True)
|
||||||
|
|||||||
Reference in New Issue
Block a user