Files
BagheeraView/settings.py
Ignacio Serantes a402828d1a First commit
2026-03-22 18:16:51 +01:00

1015 lines
50 KiB
Python

"""
Settings Module for Bagheera Image Viewer.
This module provides the main configuration dialog for the application,
allowing users to customize various aspects of its behavior, such as scanner
settings, face detection options, and thumbnail appearance.
Classes:
ModelDownloader: A QThread worker for downloading the MediaPipe model file.
SettingsDialog: The main QDialog that presents all configurable options
in a tabbed interface.
"""
import os
import shutil
import urllib.request
from PySide6.QtCore import Qt, QThread, Signal
from PySide6.QtGui import QColor, QIcon, QFont
from PySide6.QtWidgets import (
QCheckBox, QColorDialog, QComboBox, QDialog, QDialogButtonBox, QHBoxLayout,
QLabel, QLineEdit, QMessageBox, QProgressDialog, QPushButton, QSpinBox,
QTabWidget, QVBoxLayout, QWidget
)
from constants import (
APP_CONFIG, AVAILABLE_FACE_ENGINES, DEFAULT_FACE_BOX_COLOR,
DEFAULT_PET_BOX_COLOR, DEFAULT_OBJECT_BOX_COLOR, DEFAULT_LANDMARK_BOX_COLOR,
FACES_MENU_MAX_ITEMS_DEFAULT, MEDIAPIPE_FACE_MODEL_PATH, MEDIAPIPE_FACE_MODEL_URL,
AVAILABLE_PET_ENGINES, MEDIAPIPE_OBJECT_MODEL_PATH, MEDIAPIPE_OBJECT_MODEL_URL,
SCANNER_SETTINGS_DEFAULTS, SEARCH_CMD, TAGS_MENU_MAX_ITEMS_DEFAULT,
THUMBNAILS_FILENAME_LINES_DEFAULT,
THUMBNAILS_REFRESH_INTERVAL_DEFAULT, THUMBNAILS_BG_COLOR_DEFAULT,
THUMBNAILS_FILENAME_COLOR_DEFAULT, THUMBNAILS_TAGS_COLOR_DEFAULT,
THUMBNAILS_RATING_COLOR_DEFAULT, THUMBNAILS_TOOLTIP_BG_COLOR_DEFAULT,
THUMBNAILS_TOOLTIP_FG_COLOR_DEFAULT, THUMBNAILS_FILENAME_FONT_SIZE_DEFAULT,
THUMBNAILS_TAGS_LINES_DEFAULT, THUMBNAILS_TAGS_FONT_SIZE_DEFAULT,
VIEWER_AUTO_RESIZE_WINDOW_DEFAULT, VIEWER_WHEEL_SPEED_DEFAULT,
UITexts, save_app_config,
)
class ModelDownloader(QThread):
"""A thread to download the MediaPipe model file without freezing the UI."""
download_complete = Signal(bool, str) # success (bool), message (str)
def __init__(self, url, dest_path, parent=None):
super().__init__(parent)
self.url = url
self.dest_path = dest_path
def run(self):
try:
os.makedirs(os.path.dirname(self.dest_path), exist_ok=True)
with urllib.request.urlopen(self.url) as response, \
open(self.dest_path, 'wb') as out_file:
shutil.copyfileobj(response, out_file)
self.download_complete.emit(True, "")
except Exception as e:
if os.path.exists(self.dest_path):
os.remove(self.dest_path)
self.download_complete.emit(False, str(e))
class SettingsDialog(QDialog):
"""A dialog to configure application settings."""
def __init__(self, parent=None):
"""Initializes the settings dialog window.
This sets up the tabbed interface and all the individual configuration
widgets for scanner, faces, thumbnails, and viewer settings.
Args:
parent (QWidget, optional): The parent widget. Defaults to None.
"""
super().__init__(parent)
self.setWindowTitle(UITexts.MENU_SETTINGS)
self.setMinimumWidth(500)
self.scan_max_level_min = 0
self.scan_max_level_max = 10
self.current_face_color = DEFAULT_FACE_BOX_COLOR
self.current_pet_color = DEFAULT_PET_BOX_COLOR
self.current_object_color = DEFAULT_OBJECT_BOX_COLOR
self.current_landmark_color = DEFAULT_LANDMARK_BOX_COLOR
self.current_thumbs_bg_color = THUMBNAILS_BG_COLOR_DEFAULT
self.current_thumbs_filename_color = THUMBNAILS_FILENAME_COLOR_DEFAULT
self.current_thumbs_tags_color = THUMBNAILS_TAGS_COLOR_DEFAULT
self.current_thumbs_rating_color = THUMBNAILS_RATING_COLOR_DEFAULT
self.current_thumbs_tooltip_bg_color = THUMBNAILS_TOOLTIP_BG_COLOR_DEFAULT
self.current_thumbs_tooltip_fg_color = THUMBNAILS_TOOLTIP_FG_COLOR_DEFAULT
self.downloader_thread = None
layout = QVBoxLayout(self)
tabs = QTabWidget()
layout.addWidget(tabs)
# --- Create all tabs and layouts first ---
thumbs_tab = QWidget()
thumbs_layout = QVBoxLayout(thumbs_tab)
viewer_tab = QWidget()
viewer_layout = QVBoxLayout(viewer_tab)
faces_tab = QWidget()
faces_layout = QVBoxLayout(faces_tab)
scanner_tab = QWidget()
scanner_layout = QVBoxLayout(scanner_tab)
# --- Thumbnails Tab ---
mru_tags_layout = QHBoxLayout()
self.mru_tags_spin = QSpinBox()
self.mru_tags_spin.setRange(5, 100)
mru_label = QLabel(UITexts.SETTINGS_MRU_TAGS_COUNT_LABEL)
mru_tags_layout.addWidget(mru_label)
mru_tags_layout.addWidget(self.mru_tags_spin)
mru_label.setToolTip(UITexts.SETTINGS_MRU_TAGS_TOOLTIP)
self.mru_tags_spin.setToolTip(UITexts.SETTINGS_MRU_TAGS_TOOLTIP)
thumbs_layout.addLayout(mru_tags_layout)
thumbs_refresh_layout = QHBoxLayout()
self.thumbs_refresh_spin = QSpinBox()
self.thumbs_refresh_spin.setRange(50, 1000)
self.thumbs_refresh_spin.setSingleStep(10)
self.thumbs_refresh_spin.setSuffix(" ms")
thumbs_refresh_label = QLabel(UITexts.SETTINGS_THUMBS_REFRESH_LABEL)
thumbs_refresh_layout.addWidget(thumbs_refresh_label)
thumbs_refresh_layout.addWidget(self.thumbs_refresh_spin)
thumbs_refresh_label.setToolTip(UITexts.SETTINGS_THUMBS_REFRESH_TOOLTIP)
self.thumbs_refresh_spin.setToolTip(UITexts.SETTINGS_THUMBS_REFRESH_TOOLTIP)
thumbs_layout.addLayout(thumbs_refresh_layout)
thumbs_bg_color_layout = QHBoxLayout()
thumbs_bg_color_label = QLabel(UITexts.SETTINGS_THUMBS_BG_COLOR_LABEL)
self.thumbs_bg_color_btn = QPushButton()
self.thumbs_bg_color_btn.clicked.connect(self.choose_thumbs_bg_color)
thumbs_bg_color_layout.addWidget(thumbs_bg_color_label)
thumbs_bg_color_layout.addWidget(self.thumbs_bg_color_btn)
thumbs_bg_color_label.setToolTip(UITexts.SETTINGS_THUMBS_BG_COLOR_TOOLTIP)
self.thumbs_bg_color_btn.setToolTip(UITexts.SETTINGS_THUMBS_BG_COLOR_TOOLTIP)
thumbs_layout.addLayout(thumbs_bg_color_layout)
thumbs_filename_color_layout = QHBoxLayout()
thumbs_filename_color_label = QLabel(
UITexts.SETTINGS_THUMBS_FILENAME_COLOR_LABEL)
self.thumbs_filename_color_btn = QPushButton()
self.thumbs_filename_color_btn.clicked.connect(
self.choose_thumbs_filename_color)
thumbs_filename_color_layout.addWidget(thumbs_filename_color_label)
thumbs_filename_color_layout.addWidget(self.thumbs_filename_color_btn)
thumbs_filename_color_label.setToolTip(
UITexts.SETTINGS_THUMBS_FILENAME_COLOR_TOOLTIP)
self.thumbs_filename_color_btn.setToolTip(
UITexts.SETTINGS_THUMBS_FILENAME_COLOR_TOOLTIP)
thumbs_layout.addLayout(thumbs_filename_color_layout)
thumbs_tags_color_layout = QHBoxLayout()
thumbs_tags_color_label = QLabel(UITexts.SETTINGS_THUMBS_TAGS_COLOR_LABEL)
self.thumbs_tags_color_btn = QPushButton()
self.thumbs_tags_color_btn.clicked.connect(self.choose_thumbs_tags_color)
thumbs_tags_color_layout.addWidget(thumbs_tags_color_label)
thumbs_tags_color_layout.addWidget(self.thumbs_tags_color_btn)
thumbs_tags_color_label.setToolTip(UITexts.SETTINGS_THUMBS_TAGS_COLOR_TOOLTIP)
self.thumbs_tags_color_btn.setToolTip(
UITexts.SETTINGS_THUMBS_TAGS_COLOR_TOOLTIP)
thumbs_layout.addLayout(thumbs_tags_color_layout)
thumbs_rating_color_layout = QHBoxLayout()
thumbs_rating_color_label = QLabel(UITexts.SETTINGS_THUMBS_RATING_COLOR_LABEL)
self.thumbs_rating_color_btn = QPushButton()
self.thumbs_rating_color_btn.clicked.connect(self.choose_thumbs_rating_color)
thumbs_rating_color_layout.addWidget(thumbs_rating_color_label)
thumbs_rating_color_layout.addWidget(self.thumbs_rating_color_btn)
thumbs_rating_color_label.setToolTip(
UITexts.SETTINGS_THUMBS_RATING_COLOR_TOOLTIP)
self.thumbs_rating_color_btn.setToolTip(
UITexts.SETTINGS_THUMBS_RATING_COLOR_TOOLTIP)
thumbs_layout.addLayout(thumbs_rating_color_layout)
filename_font_size_layout = QHBoxLayout()
self.filename_font_size_spin = QSpinBox()
self.filename_font_size_spin.setRange(6, 16)
self.filename_font_size_spin.setSuffix(" pt")
filename_font_label = QLabel(UITexts.SETTINGS_THUMBS_FILENAME_FONT_SIZE_LABEL)
filename_font_size_layout.addWidget(filename_font_label)
filename_font_size_layout.addWidget(self.filename_font_size_spin)
filename_font_label.setToolTip(
UITexts.SETTINGS_THUMBS_FILENAME_FONT_SIZE_TOOLTIP)
self.filename_font_size_spin.setToolTip(
UITexts.SETTINGS_THUMBS_FILENAME_FONT_SIZE_TOOLTIP)
thumbs_layout.addLayout(filename_font_size_layout)
tags_font_size_layout = QHBoxLayout()
self.tags_font_size_spin = QSpinBox()
self.tags_font_size_spin.setRange(6, 16)
self.tags_font_size_spin.setSuffix(" pt")
tags_font_label = QLabel(UITexts.SETTINGS_THUMBS_TAGS_FONT_SIZE_LABEL)
tags_font_size_layout.addWidget(tags_font_label)
tags_font_size_layout.addWidget(self.tags_font_size_spin)
tags_font_label.setToolTip(UITexts.SETTINGS_THUMBS_TAGS_FONT_SIZE_TOOLTIP)
self.tags_font_size_spin.setToolTip(
UITexts.SETTINGS_THUMBS_TAGS_FONT_SIZE_TOOLTIP)
thumbs_layout.addLayout(tags_font_size_layout)
# --- Thumbs Tooltip Background Color ---
thumbs_tooltip_bg_color_layout = QHBoxLayout()
thumbs_tooltip_bg_color_label = QLabel(
UITexts.SETTINGS_THUMBS_TOOLTIP_BG_COLOR_LABEL)
self.thumbs_tooltip_bg_color_btn = QPushButton()
self.thumbs_tooltip_bg_color_btn.clicked.connect(
self.choose_thumbs_tooltip_bg_color)
thumbs_tooltip_bg_color_layout.addWidget(thumbs_tooltip_bg_color_label)
thumbs_tooltip_bg_color_layout.addWidget(self.thumbs_tooltip_bg_color_btn)
thumbs_tooltip_bg_color_label.setToolTip(
UITexts.SETTINGS_THUMBS_TOOLTIP_BG_COLOR_TOOLTIP)
self.thumbs_tooltip_bg_color_btn.setToolTip(
UITexts.SETTINGS_THUMBS_TOOLTIP_BG_COLOR_TOOLTIP)
thumbs_layout.addLayout(thumbs_tooltip_bg_color_layout)
# --- Thumbs Tooltip Foreground Color ---
thumbs_tooltip_fg_color_layout = QHBoxLayout()
thumbs_tooltip_fg_color_label = QLabel(
UITexts.SETTINGS_THUMBS_TOOLTIP_FG_COLOR_LABEL)
self.thumbs_tooltip_fg_color_btn = QPushButton()
self.thumbs_tooltip_fg_color_btn.clicked.connect(
self.choose_thumbs_tooltip_fg_color)
thumbs_tooltip_fg_color_layout.addWidget(thumbs_tooltip_fg_color_label)
thumbs_tooltip_fg_color_layout.addWidget(self.thumbs_tooltip_fg_color_btn)
thumbs_tooltip_fg_color_label.setToolTip(
UITexts.SETTINGS_THUMBS_TOOLTIP_FG_COLOR_TOOLTIP)
self.thumbs_tooltip_fg_color_btn.setToolTip(
UITexts.SETTINGS_THUMBS_TOOLTIP_FG_COLOR_TOOLTIP)
thumbs_layout.addLayout(thumbs_tooltip_fg_color_layout)
show_filename_layout = QHBoxLayout()
self.show_filename_check = QCheckBox(
UITexts.SETTINGS_THUMBS_SHOW_FILENAME_LABEL)
self.show_filename_check.setToolTip(
UITexts.SETTINGS_THUMBS_SHOW_FILENAME_TOOLTIP)
show_filename_layout.addWidget(self.show_filename_check)
thumbs_layout.addLayout(show_filename_layout)
show_rating_layout = QHBoxLayout()
self.show_rating_check = QCheckBox(UITexts.SETTINGS_THUMBS_SHOW_RATING_LABEL)
self.show_rating_check.setToolTip(UITexts.SETTINGS_THUMBS_SHOW_RATING_TOOLTIP)
show_rating_layout.addWidget(self.show_rating_check)
thumbs_layout.addLayout(show_rating_layout)
show_tags_layout = QHBoxLayout()
self.show_tags_check = QCheckBox(UITexts.SETTINGS_THUMBS_SHOW_TAGS_LABEL)
self.show_tags_check.setToolTip(UITexts.SETTINGS_THUMBS_SHOW_TAGS_TOOLTIP)
show_tags_layout.addWidget(self.show_tags_check)
thumbs_layout.addLayout(show_tags_layout)
filename_lines_layout = QHBoxLayout()
self.filename_lines_spin = QSpinBox()
self.filename_lines_spin.setRange(1, 3)
filename_lines_label = QLabel(UITexts.SETTINGS_THUMBS_FILENAME_LINES_LABEL)
filename_lines_layout.addWidget(filename_lines_label)
filename_lines_layout.addWidget(self.filename_lines_spin)
filename_lines_label.setToolTip(UITexts.SETTINGS_THUMBS_FILENAME_LINES_TOOLTIP)
self.filename_lines_spin.setToolTip(
UITexts.SETTINGS_THUMBS_FILENAME_LINES_TOOLTIP)
thumbs_layout.addLayout(filename_lines_layout)
tags_lines_layout = QHBoxLayout()
self.tags_lines_spin = QSpinBox()
self.tags_lines_spin.setRange(1, 4)
tags_lines_label = QLabel(UITexts.SETTINGS_THUMBS_TAGS_LINES_LABEL)
tags_lines_layout.addWidget(tags_lines_label)
tags_lines_layout.addWidget(self.tags_lines_spin)
tags_lines_label.setToolTip(UITexts.SETTINGS_THUMBS_TAGS_LINES_TOOLTIP)
self.tags_lines_spin.setToolTip(UITexts.SETTINGS_THUMBS_TAGS_LINES_TOOLTIP)
thumbs_layout.addLayout(tags_lines_layout)
thumbs_layout.addStretch()
# --- Scanner Tab ---
scan_max_level_layout = QHBoxLayout()
scan_max_level_label = QLabel(UITexts.SETTINGS_SCAN_MAX_LEVEL_LABEL)
self.scan_max_level_spin = QSpinBox()
self.scan_max_level_spin.setRange(self.scan_max_level_min,
self.scan_max_level_max)
scan_max_level_layout.addWidget(scan_max_level_label)
scan_max_level_layout.addWidget(self.scan_max_level_spin)
scan_max_level_label.setToolTip(UITexts.SETTINGS_SCAN_MAX_LEVEL_TOOLTIP)
self.scan_max_level_spin.setToolTip(UITexts.SETTINGS_SCAN_MAX_LEVEL_TOOLTIP)
scanner_layout.addLayout(scan_max_level_layout)
# --- Search Engine ---
search_engine_layout = QHBoxLayout()
search_engine_label = QLabel(UITexts.SETTINGS_SCANNER_SEARCH_ENGINE_LABEL)
self.search_engine_combo = QComboBox()
self.search_engine_combo.addItem(UITexts.SEARCH_ENGINE_NATIVE, "Native")
if SEARCH_CMD:
self.search_engine_combo.addItem(UITexts.SEARCH_ENGINE_BALOO, "baloosearch")
search_engine_layout.addWidget(search_engine_label)
search_engine_layout.addWidget(self.search_engine_combo)
search_engine_label.setToolTip(UITexts.SETTINGS_SCANNER_SEARCH_ENGINE_TOOLTIP)
self.search_engine_combo.setToolTip(
UITexts.SETTINGS_SCANNER_SEARCH_ENGINE_TOOLTIP)
scanner_layout.addLayout(search_engine_layout)
scan_batch_size_layout = QHBoxLayout()
scan_batch_size_label = QLabel(UITexts.SETTINGS_SCAN_BATCH_SIZE_LABEL)
self.scan_batch_size_spin = QSpinBox()
self.scan_batch_size_spin.setRange(16, 128)
scan_batch_size_layout.addWidget(scan_batch_size_label)
scan_batch_size_layout.addWidget(self.scan_batch_size_spin)
scan_batch_size_label.setToolTip(UITexts.SETTINGS_SCAN_BATCH_SIZE_TOOLTIP)
self.scan_batch_size_spin.setToolTip(UITexts.SETTINGS_SCAN_BATCH_SIZE_TOOLTIP)
scanner_layout.addLayout(scan_batch_size_layout)
scan_full_on_start_layout = QHBoxLayout()
scan_full_on_start_label = QLabel(UITexts.SETTINGS_SCAN_FULL_ON_START_LABEL)
self.scan_full_on_start_checkbox = QCheckBox()
self.scan_full_on_start_checkbox.setText("")
scan_full_on_start_layout.addWidget(scan_full_on_start_label)
scan_full_on_start_layout.addStretch()
scan_full_on_start_layout.addWidget(self.scan_full_on_start_checkbox)
scan_full_on_start_label.setToolTip(
UITexts.SETTINGS_SCAN_FULL_ON_START_TOOLTIP)
self.scan_full_on_start_checkbox.setToolTip(
UITexts.SETTINGS_SCAN_FULL_ON_START_TOOLTIP)
# Threads
threads_layout = QHBoxLayout()
threads_label = QLabel(UITexts.SETTINGS_SCAN_THREADS_LABEL)
self.threads_spin = QSpinBox()
self.threads_spin.setRange(1, 32)
threads_layout.addWidget(threads_label)
threads_layout.addWidget(self.threads_spin)
threads_label.setToolTip(UITexts.SETTINGS_SCAN_THREADS_TOOLTIP)
self.threads_spin.setToolTip(UITexts.SETTINGS_SCAN_THREADS_TOOLTIP)
scanner_layout.addLayout(threads_layout)
scanner_layout.addLayout(scan_full_on_start_layout)
scanner_layout.addStretch()
# --- Faces & People Tab ---
faces_tab = QWidget()
faces_layout = QVBoxLayout(faces_tab)
# Faces Header
faces_header = QLabel("Faces")
faces_header.setFont(QFont("Sans", 10, QFont.Bold))
faces_layout.addWidget(faces_header)
# --- Person Tags ---
person_tags_layout = QHBoxLayout()
person_tags_label = QLabel(UITexts.SETTINGS_PERSON_TAGS_LABEL)
self.person_tags_edit = QLineEdit()
self.person_tags_edit.setPlaceholderText("tag1, tag2, tag3/subtag")
self.person_tags_edit.setClearButtonEnabled(True)
person_tags_layout.addWidget(person_tags_label)
person_tags_layout.addWidget(self.person_tags_edit)
person_tags_label.setToolTip(UITexts.SETTINGS_PERSON_TAGS_TOOLTIP)
self.person_tags_edit.setToolTip(UITexts.SETTINGS_PERSON_TAGS_TOOLTIP)
faces_layout.addLayout(person_tags_layout)
if AVAILABLE_FACE_ENGINES:
face_engine_layout = QHBoxLayout()
face_engine_label = QLabel(UITexts.SETTINGS_FACE_ENGINE_LABEL)
self.face_engine_combo = QComboBox()
self.face_engine_combo.addItems(AVAILABLE_FACE_ENGINES)
self.download_model_btn = QPushButton(
UITexts.SETTINGS_DOWNLOAD_MEDIAPIPE_MODEL)
self.download_model_btn.setIcon(QIcon.fromTheme("download"))
self.download_model_btn.setToolTip(
UITexts.SETTINGS_DOWNLOAD_MEDIAPIPE_MODEL_TOOLTIP)
self.download_model_btn.clicked.connect(self.start_model_download)
face_engine_layout.addWidget(face_engine_label)
face_engine_layout.addWidget(self.face_engine_combo, 1)
face_engine_layout.addWidget(self.download_model_btn)
face_engine_label.setToolTip(UITexts.SETTINGS_FACE_ENGINE_TOOLTIP)
self.face_engine_combo.setToolTip(UITexts.SETTINGS_FACE_ENGINE_TOOLTIP)
faces_layout.addLayout(face_engine_layout)
else:
self.face_engine_combo = None
self.download_model_btn = None
face_color_layout = QHBoxLayout()
face_color_label = QLabel(UITexts.SETTINGS_FACE_COLOR_LABEL)
self.face_color_btn = QPushButton()
self.face_color_btn.clicked.connect(self.choose_face_color)
face_color_layout.addWidget(face_color_label)
face_color_layout.addWidget(self.face_color_btn)
face_color_label.setToolTip(UITexts.SETTINGS_FACE_COLOR_TOOLTIP)
self.face_color_btn.setToolTip(UITexts.SETTINGS_FACE_COLOR_TOOLTIP)
faces_layout.addLayout(face_color_layout)
face_history_layout = QHBoxLayout()
self.face_history_spin = QSpinBox()
self.face_history_spin.setRange(5, 100)
face_hist_label = QLabel(UITexts.SETTINGS_FACE_HISTORY_COUNT_LABEL)
face_history_layout.addWidget(face_hist_label)
face_history_layout.addWidget(self.face_history_spin)
face_hist_label.setToolTip(UITexts.SETTINGS_FACE_HISTORY_TOOLTIP)
self.face_history_spin.setToolTip(UITexts.SETTINGS_FACE_HISTORY_TOOLTIP)
faces_layout.addLayout(face_history_layout)
# --- Pets Section ---
faces_layout.addSpacing(10)
pets_header = QLabel("Pets")
pets_header.setFont(QFont("Sans", 10, QFont.Bold))
faces_layout.addWidget(pets_header)
pet_tags_layout = QHBoxLayout()
pet_tags_label = QLabel(UITexts.SETTINGS_PET_TAGS_LABEL)
self.pet_tags_edit = QLineEdit()
self.pet_tags_edit.setPlaceholderText("tag1, tag2, tag3/subtag")
self.pet_tags_edit.setClearButtonEnabled(True)
pet_tags_layout.addWidget(pet_tags_label)
pet_tags_layout.addWidget(self.pet_tags_edit)
pet_tags_label.setToolTip(UITexts.SETTINGS_PET_TAGS_TOOLTIP)
self.pet_tags_edit.setToolTip(UITexts.SETTINGS_PET_TAGS_TOOLTIP)
faces_layout.addLayout(pet_tags_layout)
pet_engine_layout = QHBoxLayout()
pet_engine_label = QLabel(UITexts.SETTINGS_PET_ENGINE_LABEL)
self.pet_engine_combo = QComboBox()
self.pet_engine_combo.addItems(AVAILABLE_PET_ENGINES)
self.download_pet_model_btn = QPushButton(
UITexts.SETTINGS_DOWNLOAD_MEDIAPIPE_MODEL)
self.download_pet_model_btn.setIcon(QIcon.fromTheme("download"))
self.download_pet_model_btn.setToolTip(
UITexts.SETTINGS_DOWNLOAD_MEDIAPIPE_MODEL_TOOLTIP)
self.download_pet_model_btn.clicked.connect(self.start_pet_model_download)
pet_engine_layout.addWidget(pet_engine_label)
pet_engine_layout.addWidget(self.pet_engine_combo, 1)
pet_engine_layout.addWidget(self.download_pet_model_btn)
pet_engine_label.setToolTip(UITexts.SETTINGS_PET_ENGINE_TOOLTIP)
self.pet_engine_combo.setToolTip(UITexts.SETTINGS_PET_ENGINE_TOOLTIP)
faces_layout.addLayout(pet_engine_layout)
pet_color_layout = QHBoxLayout()
pet_color_label = QLabel(UITexts.SETTINGS_PET_COLOR_LABEL)
self.pet_color_btn = QPushButton()
self.pet_color_btn.clicked.connect(self.choose_pet_color)
pet_color_layout.addWidget(pet_color_label)
pet_color_layout.addWidget(self.pet_color_btn)
pet_color_label.setToolTip(UITexts.SETTINGS_PET_COLOR_TOOLTIP)
self.pet_color_btn.setToolTip(UITexts.SETTINGS_PET_COLOR_TOOLTIP)
faces_layout.addLayout(pet_color_layout)
pet_history_layout = QHBoxLayout()
self.pet_history_spin = QSpinBox()
self.pet_history_spin.setRange(5, 100)
pet_hist_label = QLabel(UITexts.SETTINGS_PET_HISTORY_COUNT_LABEL)
pet_history_layout.addWidget(pet_hist_label)
pet_history_layout.addWidget(self.pet_history_spin)
pet_hist_label.setToolTip(UITexts.SETTINGS_PET_HISTORY_TOOLTIP)
self.pet_history_spin.setToolTip(UITexts.SETTINGS_PET_HISTORY_TOOLTIP)
faces_layout.addLayout(pet_history_layout)
# --- Object Section ---
faces_layout.addSpacing(10)
object_header = QLabel("Object")
object_header.setFont(QFont("Sans", 10, QFont.Bold))
faces_layout.addWidget(object_header)
object_tags_layout = QHBoxLayout()
object_tags_label = QLabel(UITexts.SETTINGS_OBJECT_TAGS_LABEL)
self.object_tags_edit = QLineEdit()
self.object_tags_edit.setPlaceholderText("tag1, tag2, tag3/subtag")
self.object_tags_edit.setClearButtonEnabled(True)
object_tags_layout.addWidget(object_tags_label)
object_tags_layout.addWidget(self.object_tags_edit)
object_tags_label.setToolTip(UITexts.SETTINGS_OBJECT_TAGS_TOOLTIP)
self.object_tags_edit.setToolTip(UITexts.SETTINGS_OBJECT_TAGS_TOOLTIP)
faces_layout.addLayout(object_tags_layout)
# object_engine_layout = QHBoxLayout()
# object_engine_label = QLabel(UITexts.SETTINGS_OBJECT_ENGINE_LABEL)
# self.object_engine_combo = QComboBox()
# object_engine_layout.addWidget(object_engine_label)
# object_engine_layout.addWidget(self.object_engine_combo, 1)
# object_engine_label.setToolTip(UITexts.SETTINGS_OBJECT_ENGINE_TOOLTIP)
# self.object_engine_combo.setToolTip(UITexts.SETTINGS_OBJECT_ENGINE_TOOLTIP)
# faces_layout.addLayout(object_engine_layout)
object_color_layout = QHBoxLayout()
object_color_label = QLabel(UITexts.SETTINGS_OBJECT_COLOR_LABEL)
self.object_color_btn = QPushButton()
self.object_color_btn.clicked.connect(self.choose_object_color)
object_color_layout.addWidget(object_color_label)
object_color_layout.addWidget(self.object_color_btn)
object_color_label.setToolTip(UITexts.SETTINGS_OBJECT_COLOR_TOOLTIP)
self.object_color_btn.setToolTip(UITexts.SETTINGS_OBJECT_COLOR_TOOLTIP)
faces_layout.addLayout(object_color_layout)
object_history_layout = QHBoxLayout()
self.object_history_spin = QSpinBox()
self.object_history_spin.setRange(5, 100)
object_hist_label = QLabel(UITexts.SETTINGS_OBJECT_HISTORY_COUNT_LABEL)
object_history_layout.addWidget(object_hist_label)
object_history_layout.addWidget(self.object_history_spin)
object_hist_label.setToolTip(UITexts.SETTINGS_OBJECT_HISTORY_TOOLTIP)
self.object_history_spin.setToolTip(UITexts.SETTINGS_OBJECT_HISTORY_TOOLTIP)
faces_layout.addLayout(object_history_layout)
# --- Landmark Section ---
faces_layout.addSpacing(10)
landmark_header = QLabel("Landmark")
landmark_header.setFont(QFont("Sans", 10, QFont.Bold))
faces_layout.addWidget(landmark_header)
landmark_tags_layout = QHBoxLayout()
landmark_tags_label = QLabel(UITexts.SETTINGS_LANDMARK_TAGS_LABEL)
self.landmark_tags_edit = QLineEdit()
self.landmark_tags_edit.setPlaceholderText("tag1, tag2, tag3/subtag")
self.landmark_tags_edit.setClearButtonEnabled(True)
landmark_tags_layout.addWidget(landmark_tags_label)
landmark_tags_layout.addWidget(self.landmark_tags_edit)
landmark_tags_label.setToolTip(UITexts.SETTINGS_LANDMARK_TAGS_TOOLTIP)
self.landmark_tags_edit.setToolTip(UITexts.SETTINGS_LANDMARK_TAGS_TOOLTIP)
faces_layout.addLayout(landmark_tags_layout)
# landmark_engine_layout = QHBoxLayout()
# landmark_engine_label = QLabel(UITexts.SETTINGS_LANDMARK_ENGINE_LABEL)
# self.landmark_engine_combo = QComboBox()
# landmark_engine_layout.addWidget(landmark_engine_label)
# landmark_engine_layout.addWidget(self.landmark_engine_combo, 1)
# landmark_engine_label.setToolTip(UITexts.SETTINGS_LANDMARK_ENGINE_TOOLTIP)
# self.landmark_engine_combo.setToolTip(UITexts.SETTINGS_LANDMARK_ENGINE_TOOLTIP)
# faces_layout.addLayout(landmark_engine_layout)
landmark_color_layout = QHBoxLayout()
landmark_color_label = QLabel(UITexts.SETTINGS_LANDMARK_COLOR_LABEL)
self.landmark_color_btn = QPushButton()
self.landmark_color_btn.clicked.connect(self.choose_landmark_color)
landmark_color_layout.addWidget(landmark_color_label)
landmark_color_layout.addWidget(self.landmark_color_btn)
landmark_color_label.setToolTip(UITexts.SETTINGS_LANDMARK_COLOR_TOOLTIP)
self.landmark_color_btn.setToolTip(UITexts.SETTINGS_LANDMARK_COLOR_TOOLTIP)
faces_layout.addLayout(landmark_color_layout)
landmark_history_layout = QHBoxLayout()
self.landmark_history_spin = QSpinBox()
self.landmark_history_spin.setRange(5, 100)
landmark_hist_label = QLabel(UITexts.SETTINGS_LANDMARK_HISTORY_COUNT_LABEL)
landmark_history_layout.addWidget(landmark_hist_label)
landmark_history_layout.addWidget(self.landmark_history_spin)
landmark_hist_label.setToolTip(UITexts.SETTINGS_LANDMARK_HISTORY_TOOLTIP)
self.landmark_history_spin.setToolTip(UITexts.SETTINGS_LANDMARK_HISTORY_TOOLTIP)
faces_layout.addLayout(landmark_history_layout)
faces_layout.addStretch()
# --- Viewer Tab ---
viewer_wheel_layout = QHBoxLayout()
viewer_wheel_label = QLabel(UITexts.SETTINGS_VIEWER_WHEEL_SPEED_LABEL)
self.viewer_wheel_spin = QSpinBox()
self.viewer_wheel_spin.setRange(1, 10)
viewer_wheel_layout.addWidget(viewer_wheel_label)
viewer_wheel_layout.addWidget(self.viewer_wheel_spin)
viewer_wheel_label.setToolTip(UITexts.SETTINGS_VIEWER_WHEEL_SPEED_TOOLTIP)
self.viewer_wheel_spin.setToolTip(UITexts.SETTINGS_VIEWER_WHEEL_SPEED_TOOLTIP)
viewer_layout.addLayout(viewer_wheel_layout)
viewer_auto_resize_layout = QHBoxLayout()
self.viewer_auto_resize_check = QCheckBox(
UITexts.SETTINGS_VIEWER_AUTO_RESIZE_LABEL)
self.viewer_auto_resize_check.setToolTip(
UITexts.SETTINGS_VIEWER_AUTO_RESIZE_TOOLTIP)
viewer_auto_resize_layout.addWidget(self.viewer_auto_resize_check)
viewer_layout.addLayout(viewer_auto_resize_layout)
filmstrip_pos_layout = QHBoxLayout()
filmstrip_pos_label = QLabel(UITexts.MENU_FILMSTRIP_POSITION)
self.filmstrip_pos_combo = QComboBox()
self.filmstrip_pos_combo.addItems([
UITexts.FILMSTRIP_BOTTOM,
UITexts.FILMSTRIP_LEFT,
UITexts.FILMSTRIP_TOP,
UITexts.FILMSTRIP_RIGHT
])
filmstrip_pos_layout.addWidget(filmstrip_pos_label)
filmstrip_pos_layout.addWidget(self.filmstrip_pos_combo)
filmstrip_pos_label.setToolTip(UITexts.FILMSTRIP_POS_CHANGED_INFO)
self.filmstrip_pos_combo.setToolTip(UITexts.FILMSTRIP_POS_CHANGED_INFO)
viewer_layout.addLayout(filmstrip_pos_layout)
viewer_layout.addStretch()
# Add tabs in the new order
tabs.addTab(thumbs_tab, UITexts.SETTINGS_GROUP_THUMBNAILS)
tabs.addTab(viewer_tab, UITexts.SETTINGS_GROUP_VIEWER)
tabs.addTab(faces_tab, UITexts.SETTINGS_GROUP_FACES)
tabs.addTab(scanner_tab, UITexts.SETTINGS_GROUP_SCANNER)
# --- Button Box ---
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
button_box.accepted.connect(self.accept)
button_box.rejected.connect(self.reject)
layout.addWidget(button_box)
# Load current settings
self.load_settings()
def load_settings(self):
"""Loads settings from the application configuration."""
# Example:
# theme = APP_CONFIG.get("theme", "System")
# self.theme_combo.setCurrentText(theme)
scan_max_level = APP_CONFIG.get(
"scan_max_level", SCANNER_SETTINGS_DEFAULTS["scan_max_level"])
scan_batch_size = APP_CONFIG.get(
"scan_batch_size", SCANNER_SETTINGS_DEFAULTS["scan_batch_size"])
scan_full_on_start = APP_CONFIG.get(
"scan_full_on_start", SCANNER_SETTINGS_DEFAULTS["scan_full_on_start"])
scan_threads = APP_CONFIG.get(
"generation_threads",
SCANNER_SETTINGS_DEFAULTS.get("generation_threads", 4))
search_engine = APP_CONFIG.get(
"search_engine", SCANNER_SETTINGS_DEFAULTS.get("search_engine", "Native"))
person_tags = APP_CONFIG.get(
"person_tags", SCANNER_SETTINGS_DEFAULTS["person_tags"])
pet_tags = APP_CONFIG.get("pet_tags", "")
object_tags = APP_CONFIG.get("object_tags", "")
landmark_tags = APP_CONFIG.get("landmark_tags", "")
face_detection_engine = APP_CONFIG.get("face_detection_engine")
pet_detection_engine = APP_CONFIG.get("pet_detection_engine")
object_detection_engine = APP_CONFIG.get("object_detection_engine")
landmark_detection_engine = APP_CONFIG.get("landmark_detection_engine")
face_color = APP_CONFIG.get("face_box_color", DEFAULT_FACE_BOX_COLOR)
pet_color = APP_CONFIG.get("pet_box_color", DEFAULT_PET_BOX_COLOR)
object_color = APP_CONFIG.get("object_box_color", DEFAULT_OBJECT_BOX_COLOR)
landmark_color = APP_CONFIG.get("landmark_box_color",
DEFAULT_LANDMARK_BOX_COLOR)
mru_tags_count = APP_CONFIG.get(
"tags_menu_max_items", TAGS_MENU_MAX_ITEMS_DEFAULT)
face_history_count = APP_CONFIG.get(
"faces_menu_max_items", FACES_MENU_MAX_ITEMS_DEFAULT)
pet_history_count = APP_CONFIG.get(
"pets_menu_max_items", FACES_MENU_MAX_ITEMS_DEFAULT)
object_history_count = APP_CONFIG.get(
"object_menu_max_items", FACES_MENU_MAX_ITEMS_DEFAULT)
landmark_history_count = APP_CONFIG.get(
"landmark_menu_max_items", FACES_MENU_MAX_ITEMS_DEFAULT)
thumbs_refresh_interval = APP_CONFIG.get(
"thumbnails_refresh_interval", THUMBNAILS_REFRESH_INTERVAL_DEFAULT)
thumbs_bg_color = APP_CONFIG.get(
"thumbnails_bg_color", THUMBNAILS_BG_COLOR_DEFAULT)
thumbs_filename_color = APP_CONFIG.get(
"thumbnails_filename_color", THUMBNAILS_FILENAME_COLOR_DEFAULT)
thumbs_tags_color = APP_CONFIG.get(
"thumbnails_tags_color", THUMBNAILS_TAGS_COLOR_DEFAULT)
thumbs_rating_color = APP_CONFIG.get("thumbnails_rating_color",
THUMBNAILS_RATING_COLOR_DEFAULT)
thumbs_tooltip_bg_color = APP_CONFIG.get("thumbnails_tooltip_bg_color",
THUMBNAILS_TOOLTIP_BG_COLOR_DEFAULT)
thumbs_tooltip_fg_color = APP_CONFIG.get("thumbnails_tooltip_fg_color",
THUMBNAILS_TOOLTIP_FG_COLOR_DEFAULT)
thumbs_filename_font_size = \
APP_CONFIG.get("thumbnails_filename_font_size",
THUMBNAILS_FILENAME_FONT_SIZE_DEFAULT)
thumbs_tags_font_size = APP_CONFIG.get("thumbnails_tags_font_size",
THUMBNAILS_TAGS_FONT_SIZE_DEFAULT)
viewer_wheel_speed = APP_CONFIG.get("viewer_wheel_speed",
VIEWER_WHEEL_SPEED_DEFAULT)
viewer_auto_resize = APP_CONFIG.get("viewer_auto_resize_window",
VIEWER_AUTO_RESIZE_WINDOW_DEFAULT)
thumbs_filename_lines = APP_CONFIG.get("thumbnails_filename_lines",
THUMBNAILS_FILENAME_LINES_DEFAULT)
thumbs_tags_lines = APP_CONFIG.get("thumbnails_tags_lines",
THUMBNAILS_TAGS_LINES_DEFAULT)
show_filename = APP_CONFIG.get("thumbnails_show_filename", True)
show_rating = APP_CONFIG.get("thumbnails_show_rating", True)
show_tags = APP_CONFIG.get("thumbnails_show_tags", True)
filmstrip_position = APP_CONFIG.get("filmstrip_position", "bottom")
self.scan_max_level_spin.setValue(scan_max_level)
self.scan_batch_size_spin.setValue(scan_batch_size)
self.threads_spin.setValue(scan_threads)
# Set search engine
index = self.search_engine_combo.findData(search_engine)
if index != -1:
self.search_engine_combo.setCurrentIndex(index)
self.scan_full_on_start_checkbox.setChecked(scan_full_on_start)
self.person_tags_edit.setText(person_tags)
self.pet_tags_edit.setText(pet_tags)
self.object_tags_edit.setText(object_tags)
self.landmark_tags_edit.setText(landmark_tags)
self.set_button_color(face_color)
self.set_pet_button_color(pet_color)
self.set_object_button_color(object_color)
self.set_landmark_button_color(landmark_color)
if self.face_engine_combo and face_detection_engine in AVAILABLE_FACE_ENGINES:
self.face_engine_combo.setCurrentText(face_detection_engine)
if self.pet_engine_combo and pet_detection_engine in AVAILABLE_PET_ENGINES:
self.pet_engine_combo.setCurrentText(pet_detection_engine)
if object_detection_engine and hasattr(self, "object_engine_combo"):
self.object_engine_combo.setCurrentText(object_detection_engine)
if landmark_detection_engine and hasattr(self, "landmark_engine_combo"):
self.landmark_engine_combo.setCurrentText(landmark_detection_engine)
self.mru_tags_spin.setValue(mru_tags_count)
self.face_history_spin.setValue(face_history_count)
self.pet_history_spin.setValue(pet_history_count)
self.object_history_spin.setValue(object_history_count)
self.landmark_history_spin.setValue(landmark_history_count)
self.thumbs_refresh_spin.setValue(thumbs_refresh_interval)
self.set_thumbs_bg_button_color(thumbs_bg_color)
self.set_thumbs_filename_button_color(thumbs_filename_color)
self.set_thumbs_tags_button_color(thumbs_tags_color)
self.set_thumbs_rating_button_color(thumbs_rating_color)
self.set_thumbs_tooltip_bg_button_color(thumbs_tooltip_bg_color)
self.set_thumbs_tooltip_fg_button_color(thumbs_tooltip_fg_color)
self.filename_font_size_spin.setValue(thumbs_filename_font_size)
self.tags_font_size_spin.setValue(thumbs_tags_font_size)
self.viewer_wheel_spin.setValue(viewer_wheel_speed)
self.viewer_auto_resize_check.setChecked(viewer_auto_resize)
self.filename_lines_spin.setValue(thumbs_filename_lines)
self.tags_lines_spin.setValue(thumbs_tags_lines)
self.show_filename_check.setChecked(show_filename)
self.show_rating_check.setChecked(show_rating)
self.show_tags_check.setChecked(show_tags)
pos_map = {
'bottom': UITexts.FILMSTRIP_BOTTOM,
'left': UITexts.FILMSTRIP_LEFT,
'top': UITexts.FILMSTRIP_TOP,
'right': UITexts.FILMSTRIP_RIGHT
}
self.filmstrip_pos_combo.setCurrentText(
pos_map.get(filmstrip_position, UITexts.FILMSTRIP_BOTTOM))
self.update_mediapipe_status()
def set_button_color(self, color_str):
"""Sets the background color of the button and stores the value."""
self.face_color_btn.setStyleSheet(
f"background-color: {color_str}; border: 1px solid gray;")
self.current_face_color = color_str
def choose_face_color(self):
"""Opens a color picker dialog."""
color = QColorDialog.getColor(QColor(self.current_face_color), self)
if color.isValid():
self.set_button_color(color.name())
def set_pet_button_color(self, color_str):
"""Sets the background color of the pet button and stores the value."""
self.pet_color_btn.setStyleSheet(
f"background-color: {color_str}; border: 1px solid gray;")
self.current_pet_color = color_str
def choose_pet_color(self):
"""Opens a color picker dialog for pet box."""
color = QColorDialog.getColor(QColor(self.current_pet_color), self)
if color.isValid():
self.set_pet_button_color(color.name())
def set_object_button_color(self, color_str):
"""Sets the background color of the object button."""
self.object_color_btn.setStyleSheet(
f"background-color: {color_str}; border: 1px solid gray;")
self.current_object_color = color_str
def choose_object_color(self):
"""Opens a color picker dialog for object box."""
color = QColorDialog.getColor(QColor(self.current_object_color), self)
if color.isValid():
self.set_object_button_color(color.name())
def set_landmark_button_color(self, color_str):
"""Sets the background color of the landmark button."""
self.landmark_color_btn.setStyleSheet(
f"background-color: {color_str}; border: 1px solid gray;")
self.current_landmark_color = color_str
def choose_landmark_color(self):
"""Opens a color picker dialog for landmark box."""
color = QColorDialog.getColor(QColor(self.current_landmark_color), self)
if color.isValid():
self.set_landmark_button_color(color.name())
def set_thumbs_bg_button_color(self, color_str):
"""Sets the background color of the button and stores the value."""
self.thumbs_bg_color_btn.setStyleSheet(
f"background-color: {color_str}; border: 1px solid gray;")
self.current_thumbs_bg_color = color_str
def choose_thumbs_bg_color(self):
"""Opens a color picker dialog."""
color = QColorDialog.getColor(QColor(self.current_thumbs_bg_color), self)
if color.isValid():
self.set_thumbs_bg_button_color(color.name())
def set_thumbs_filename_button_color(self, color_str):
"""Sets the background color of the button and stores the value."""
self.thumbs_filename_color_btn.setStyleSheet(
f"background-color: {color_str}; border: 1px solid gray;")
self.current_thumbs_filename_color = color_str
def choose_thumbs_filename_color(self):
"""Opens a color picker dialog."""
color = QColorDialog.getColor(QColor(self.current_thumbs_filename_color), self)
if color.isValid():
self.set_thumbs_filename_button_color(color.name())
def set_thumbs_tags_button_color(self, color_str):
"""Sets the background color of the button and stores the value."""
self.thumbs_tags_color_btn.setStyleSheet(
f"background-color: {color_str}; border: 1px solid gray;")
self.current_thumbs_tags_color = color_str
def choose_thumbs_tags_color(self):
"""Opens a color picker dialog."""
color = QColorDialog.getColor(QColor(self.current_thumbs_tags_color), self)
if color.isValid():
self.set_thumbs_tags_button_color(color.name())
def set_thumbs_rating_button_color(self, color_str):
"""Sets the background color of the button and stores the value."""
self.thumbs_rating_color_btn.setStyleSheet(
f"background-color: {color_str}; border: 1px solid gray;")
self.current_thumbs_rating_color = color_str
def choose_thumbs_rating_color(self):
"""Opens a color picker dialog."""
color = QColorDialog.getColor(QColor(self.current_thumbs_rating_color), self)
if color.isValid():
self.set_thumbs_rating_button_color(color.name())
def set_thumbs_tooltip_fg_button_color(self, color_str):
"""Sets the background color of the button and stores the value."""
self.thumbs_tooltip_fg_color_btn.setStyleSheet(
f"background-color: {color_str}; border: 1px solid gray;")
self.current_thumbs_tooltip_fg_color = color_str
def choose_thumbs_tooltip_fg_color(self):
"""Opens a color picker dialog."""
color = QColorDialog.getColor(
QColor(self.current_thumbs_tooltip_fg_color), self)
if color.isValid():
self.set_thumbs_tooltip_fg_button_color(color.name())
def set_thumbs_tooltip_bg_button_color(self, color_str):
"""Sets the background color of the button and stores the value."""
self.thumbs_tooltip_bg_color_btn.setStyleSheet(
f"background-color: {color_str}; border: 1px solid gray;")
self.current_thumbs_tooltip_bg_color = color_str
def choose_thumbs_tooltip_bg_color(self):
"""Opens a color picker dialog."""
color = QColorDialog.getColor(
QColor(self.current_thumbs_tooltip_bg_color), self)
if color.isValid():
self.set_thumbs_tooltip_bg_button_color(color.name())
def update_mediapipe_status(self):
"""Checks for MediaPipe model file and updates UI accordingly."""
if "mediapipe" not in AVAILABLE_FACE_ENGINES or not self.face_engine_combo:
if self.download_model_btn:
self.download_model_btn.hide()
return
model_exists = os.path.exists(MEDIAPIPE_FACE_MODEL_PATH)
mediapipe_index = self.face_engine_combo.findText("mediapipe")
if mediapipe_index != -1:
item = self.face_engine_combo.model().item(mediapipe_index)
if item:
item.setEnabled(model_exists)
if self.download_model_btn:
self.download_model_btn.setVisible(not model_exists)
if self.face_engine_combo.currentText() == "mediapipe" and not model_exists:
if self.face_engine_combo.count() > 1:
for i in range(self.face_engine_combo.count()):
if self.face_engine_combo.model().item(i).isEnabled():
self.face_engine_combo.setCurrentIndex(i)
break
if "mediapipe" not in AVAILABLE_PET_ENGINES or not self.pet_engine_combo:
if self.download_pet_model_btn:
self.download_pet_model_btn.hide()
return
pet_model_exists = os.path.exists(MEDIAPIPE_OBJECT_MODEL_PATH)
if self.download_pet_model_btn:
self.download_pet_model_btn.setVisible(not pet_model_exists)
def start_model_download(self):
"""Starts the background thread to download the MediaPipe model."""
self.downloader_thread = ModelDownloader(
MEDIAPIPE_FACE_MODEL_URL, MEDIAPIPE_FACE_MODEL_PATH, self)
self.downloader_thread.download_complete.connect(self.on_download_finished)
self.downloader_thread.finished.connect(self._on_downloader_finished)
self.progress_dialog = QProgressDialog(
UITexts.MEDIAPIPE_DOWNLOADING_TEXT, UITexts.CANCEL, 0, 0, self)
self.progress_dialog.setWindowTitle(UITexts.MEDIAPIPE_DOWNLOADING_TITLE)
self.progress_dialog.setWindowModality(Qt.WindowModal)
self.progress_dialog.show()
self.downloader_thread.start()
def start_pet_model_download(self):
"""Starts the background thread to download the MediaPipe Object model."""
self.downloader_thread = ModelDownloader(
MEDIAPIPE_OBJECT_MODEL_URL, MEDIAPIPE_OBJECT_MODEL_PATH, self)
self.downloader_thread.download_complete.connect(self.on_download_finished)
self.downloader_thread.finished.connect(self._on_downloader_finished)
self.progress_dialog = QProgressDialog(
UITexts.MEDIAPIPE_DOWNLOADING_TEXT, UITexts.CANCEL, 0, 0, self)
self.progress_dialog.setWindowTitle(UITexts.MEDIAPIPE_DOWNLOADING_TITLE)
self.progress_dialog.setWindowModality(Qt.WindowModal)
self.progress_dialog.show()
self.downloader_thread.start()
def accept(self):
"""Saves settings and closes the dialog."""
APP_CONFIG["scan_max_level"] = self.scan_max_level_spin.value()
APP_CONFIG["generation_threads"] = self.threads_spin.value()
APP_CONFIG["scan_batch_size"] = self.scan_batch_size_spin.value()
APP_CONFIG["search_engine"] = self.search_engine_combo.currentData()
APP_CONFIG["scan_full_on_start"] = self.scan_full_on_start_checkbox.isChecked()
APP_CONFIG["person_tags"] = self.person_tags_edit.text()
APP_CONFIG["pet_tags"] = self.pet_tags_edit.text()
APP_CONFIG["object_tags"] = self.object_tags_edit.text()
APP_CONFIG["landmark_tags"] = self.landmark_tags_edit.text()
APP_CONFIG["face_box_color"] = self.current_face_color
APP_CONFIG["pet_box_color"] = self.current_pet_color
APP_CONFIG["object_box_color"] = self.current_object_color
APP_CONFIG["landmark_box_color"] = self.current_landmark_color
APP_CONFIG["tags_menu_max_items"] = self.mru_tags_spin.value()
APP_CONFIG["faces_menu_max_items"] = self.face_history_spin.value()
APP_CONFIG["pets_menu_max_items"] = self.pet_history_spin.value()
APP_CONFIG["object_menu_max_items"] = self.object_history_spin.value()
APP_CONFIG["landmark_menu_max_items"] = self.landmark_history_spin.value()
APP_CONFIG["thumbnails_refresh_interval"] = self.thumbs_refresh_spin.value()
APP_CONFIG["thumbnails_bg_color"] = self.current_thumbs_bg_color
APP_CONFIG["thumbnails_filename_color"] = self.current_thumbs_filename_color
APP_CONFIG["thumbnails_tags_color"] = self.current_thumbs_tags_color
APP_CONFIG["thumbnails_rating_color"] = self.current_thumbs_rating_color
APP_CONFIG["thumbnails_tooltip_bg_color"] = \
self.current_thumbs_tooltip_bg_color
APP_CONFIG["thumbnails_tooltip_fg_color"] = \
self.current_thumbs_tooltip_fg_color
APP_CONFIG["thumbnails_filename_font_size"] = \
self.filename_font_size_spin.value()
APP_CONFIG["thumbnails_tags_font_size"] = self.tags_font_size_spin.value()
APP_CONFIG["thumbnails_filename_lines"] = self.filename_lines_spin.value()
APP_CONFIG["thumbnails_tags_lines"] = self.tags_lines_spin.value()
APP_CONFIG["thumbnails_show_filename"] = self.show_filename_check.isChecked()
APP_CONFIG["thumbnails_show_rating"] = self.show_rating_check.isChecked()
APP_CONFIG["thumbnails_show_tags"] = self.show_tags_check.isChecked()
APP_CONFIG["viewer_wheel_speed"] = self.viewer_wheel_spin.value()
APP_CONFIG["viewer_auto_resize_window"] = \
self.viewer_auto_resize_check.isChecked()
if self.face_engine_combo:
APP_CONFIG["face_detection_engine"] = self.face_engine_combo.currentText()
APP_CONFIG["pet_detection_engine"] = self.pet_engine_combo.currentText()
if hasattr(self, "object_engine_combo"):
APP_CONFIG["object_detection_engine"] = \
self.object_engine_combo.currentText()
if hasattr(self, "landmark_engine_combo"):
APP_CONFIG["landmark_detection_engine"] = \
self.landmark_engine_combo.currentText()
pos_map_inv = {
UITexts.FILMSTRIP_BOTTOM: 'bottom',
UITexts.FILMSTRIP_LEFT: 'left',
UITexts.FILMSTRIP_TOP: 'top',
UITexts.FILMSTRIP_RIGHT: 'right'
}
selected_text = self.filmstrip_pos_combo.currentText()
APP_CONFIG["filmstrip_position"] = pos_map_inv.get(selected_text, 'bottom')
save_app_config()
super().accept()
def on_download_finished(self, success, message):
"""Handles the result of the model download thread."""
self.progress_dialog.close()
if success:
QMessageBox.information(
self, UITexts.MEDIAPIPE_DOWNLOAD_SUCCESS_TITLE,
UITexts.MEDIAPIPE_DOWNLOAD_SUCCESS_TEXT)
else:
QMessageBox.critical(self, UITexts.MEDIAPIPE_DOWNLOAD_ERROR_TITLE,
UITexts.MEDIAPIPE_DOWNLOAD_ERROR_TEXT.format(message))
self.update_mediapipe_status()
def _on_downloader_finished(self):
self.downloader_thread = None