v0.9.19
This commit is contained in:
96
settings.py
96
settings.py
@@ -55,7 +55,7 @@ class DuplicateFileCounter(QThread):
|
||||
|
||||
def stop(self):
|
||||
self._abort = True
|
||||
self.wait() # Add this line
|
||||
self.wait()
|
||||
|
||||
def run(self):
|
||||
count = 0
|
||||
@@ -68,7 +68,8 @@ class DuplicateFileCounter(QThread):
|
||||
if self._abort:
|
||||
break
|
||||
abs_root = os.path.abspath(root)
|
||||
dirs[:] = [d for d in dirs if os.path.join(abs_root, d) not in self.blacklist]
|
||||
dirs[:] = [d for d in dirs
|
||||
if os.path.join(abs_root, d) not in self.blacklist]
|
||||
if abs_root in self.blacklist:
|
||||
continue
|
||||
for f in files:
|
||||
@@ -422,7 +423,8 @@ class SettingsDialog(QDialog):
|
||||
method_layout = QHBoxLayout()
|
||||
method_label = QLabel(UITexts.SETTINGS_DUPLICATE_METHOD_LABEL)
|
||||
self.duplicate_method_combo = QComboBox()
|
||||
self.duplicate_method_combo.addItem(UITexts.METHOD_HISTOGRAM_HASHING, "histogram_hashing")
|
||||
self.duplicate_method_combo.addItem(
|
||||
UITexts.METHOD_HISTOGRAM_HASHING, "histogram_hashing")
|
||||
self.duplicate_method_combo.addItem(UITexts.METHOD_RESNET, "resnet")
|
||||
|
||||
self.duplicate_method_combo.setEnabled(HAVE_IMAGEHASH)
|
||||
@@ -437,7 +439,8 @@ class SettingsDialog(QDialog):
|
||||
method_layout.addWidget(method_label)
|
||||
method_layout.addWidget(self.duplicate_method_combo)
|
||||
method_label.setToolTip(UITexts.SETTINGS_DUPLICATE_METHOD_TOOLTIP)
|
||||
self.duplicate_method_combo.setToolTip(UITexts.SETTINGS_DUPLICATE_METHOD_TOOLTIP)
|
||||
self.duplicate_method_combo.setToolTip(
|
||||
UITexts.SETTINGS_DUPLICATE_METHOD_TOOLTIP)
|
||||
duplicates_layout.addLayout(method_layout)
|
||||
|
||||
threshold_layout = QHBoxLayout()
|
||||
@@ -454,7 +457,8 @@ class SettingsDialog(QDialog):
|
||||
threshold_layout.addWidget(self.duplicate_threshold_value_label)
|
||||
|
||||
threshold_label.setToolTip(UITexts.SETTINGS_DUPLICATE_THRESHOLD_TOOLTIP)
|
||||
self.duplicate_threshold_slider.setToolTip(UITexts.SETTINGS_DUPLICATE_THRESHOLD_TOOLTIP)
|
||||
self.duplicate_threshold_slider.setToolTip(
|
||||
UITexts.SETTINGS_DUPLICATE_THRESHOLD_TOOLTIP)
|
||||
|
||||
self.duplicate_threshold_slider.valueChanged.connect(
|
||||
lambda v: self.duplicate_threshold_value_label.setText(f"{v}%"))
|
||||
@@ -485,14 +489,16 @@ class SettingsDialog(QDialog):
|
||||
|
||||
# Whitelist
|
||||
wl_cont, self.duplicate_whitelist_list, wl_add, wl_rem = create_path_list_ui(
|
||||
UITexts.SETTINGS_DUPLICATE_WHITELIST_LABEL, UITexts.SETTINGS_DUPLICATE_WHITELIST_TOOLTIP)
|
||||
UITexts.SETTINGS_DUPLICATE_WHITELIST_LABEL,
|
||||
UITexts.SETTINGS_DUPLICATE_WHITELIST_TOOLTIP)
|
||||
wl_add.clicked.connect(self.add_whitelist_path)
|
||||
wl_rem.clicked.connect(self.remove_whitelist_path)
|
||||
duplicates_layout.addWidget(wl_cont)
|
||||
|
||||
# Blacklist
|
||||
bl_cont, self.duplicate_blacklist_list, bl_add, bl_rem = create_path_list_ui(
|
||||
UITexts.SETTINGS_DUPLICATE_BLACKLIST_LABEL, UITexts.SETTINGS_DUPLICATE_BLACKLIST_TOOLTIP)
|
||||
UITexts.SETTINGS_DUPLICATE_BLACKLIST_LABEL,
|
||||
UITexts.SETTINGS_DUPLICATE_BLACKLIST_TOOLTIP)
|
||||
bl_add.clicked.connect(self.add_blacklist_path)
|
||||
bl_rem.clicked.connect(self.remove_blacklist_path)
|
||||
duplicates_layout.addWidget(bl_cont)
|
||||
@@ -500,7 +506,8 @@ class SettingsDialog(QDialog):
|
||||
# Image Count Layout
|
||||
count_layout = QHBoxLayout()
|
||||
self.duplicate_scan_count_label = QLabel()
|
||||
self.duplicate_scan_count_label.setStyleSheet("color: #3498db; font-weight: bold;")
|
||||
self.duplicate_scan_count_label.setStyleSheet(
|
||||
"color: #3498db; font-weight: bold;")
|
||||
self.duplicate_scan_progress = QProgressBar()
|
||||
self.duplicate_scan_progress.setRange(0, 0) # Indeterminate mode
|
||||
self.duplicate_scan_progress.setFixedHeight(10)
|
||||
@@ -517,20 +524,27 @@ class SettingsDialog(QDialog):
|
||||
self.count_update_timer.setInterval(500)
|
||||
self.count_update_timer.timeout.connect(self.update_duplicate_scan_count)
|
||||
|
||||
self.duplicate_whitelist_list.model().rowsInserted.connect(lambda *args: self.count_update_timer.start())
|
||||
self.duplicate_whitelist_list.model().rowsRemoved.connect(lambda *args: self.count_update_timer.start())
|
||||
self.duplicate_blacklist_list.model().rowsInserted.connect(lambda *args: self.count_update_timer.start())
|
||||
self.duplicate_blacklist_list.model().rowsRemoved.connect(lambda *args: self.count_update_timer.start())
|
||||
self.duplicate_whitelist_list.model().rowsInserted.connect(
|
||||
lambda *args: self.count_update_timer.start())
|
||||
self.duplicate_whitelist_list.model().rowsRemoved.connect(
|
||||
lambda *args: self.count_update_timer.start())
|
||||
self.duplicate_blacklist_list.model().rowsInserted.connect(
|
||||
lambda *args: self.count_update_timer.start())
|
||||
self.duplicate_blacklist_list.model().rowsRemoved.connect(
|
||||
lambda *args: self.count_update_timer.start())
|
||||
|
||||
self.default_delete_to_trash_checkbox = QCheckBox(UITexts.SETTINGS_DEFAULT_DELETE_TO_TRASH_LABEL)
|
||||
self.default_delete_to_trash_checkbox.setToolTip(UITexts.SETTINGS_DEFAULT_DELETE_TO_TRASH_TOOLTIP)
|
||||
self.default_delete_to_trash_checkbox = QCheckBox(
|
||||
UITexts.SETTINGS_DEFAULT_DELETE_TO_TRASH_LABEL)
|
||||
self.default_delete_to_trash_checkbox.setToolTip(
|
||||
UITexts.SETTINGS_DEFAULT_DELETE_TO_TRASH_TOOLTIP)
|
||||
duplicates_layout.addWidget(self.default_delete_to_trash_checkbox)
|
||||
|
||||
|
||||
duplicates_layout.addLayout(threshold_layout)
|
||||
|
||||
self.duplicate_confirm_delete_checkbox = QCheckBox(UITexts.SETTINGS_DUPLICATE_CONFIRM_DELETE_LABEL)
|
||||
self.duplicate_confirm_delete_checkbox.setToolTip(UITexts.SETTINGS_DUPLICATE_CONFIRM_DELETE_TOOLTIP)
|
||||
self.duplicate_confirm_delete_checkbox = QCheckBox(
|
||||
UITexts.SETTINGS_DUPLICATE_CONFIRM_DELETE_LABEL)
|
||||
self.duplicate_confirm_delete_checkbox.setToolTip(
|
||||
UITexts.SETTINGS_DUPLICATE_CONFIRM_DELETE_TOOLTIP)
|
||||
duplicates_layout.addWidget(self.duplicate_confirm_delete_checkbox)
|
||||
|
||||
duplicates_layout.addStretch()
|
||||
@@ -945,10 +959,12 @@ class SettingsDialog(QDialog):
|
||||
duplicate_confirm_delete = APP_CONFIG.get("duplicate_confirm_delete", True)
|
||||
self.duplicate_confirm_delete_checkbox.setChecked(duplicate_confirm_delete)
|
||||
|
||||
duplicate_whitelist = APP_CONFIG.get("duplicate_whitelist", SCANNER_SETTINGS_DEFAULTS["duplicate_whitelist"])
|
||||
duplicate_whitelist = APP_CONFIG.get(
|
||||
"duplicate_whitelist", SCANNER_SETTINGS_DEFAULTS["duplicate_whitelist"])
|
||||
for p in [x.strip() for x in duplicate_whitelist.split(",") if x.strip()]:
|
||||
self._add_path_to_list(self.duplicate_whitelist_list, p)
|
||||
duplicate_blacklist = APP_CONFIG.get("duplicate_blacklist", SCANNER_SETTINGS_DEFAULTS["duplicate_blacklist"])
|
||||
duplicate_blacklist = APP_CONFIG.get(
|
||||
"duplicate_blacklist", SCANNER_SETTINGS_DEFAULTS["duplicate_blacklist"])
|
||||
for p in [x.strip() for x in duplicate_blacklist.split(",") if x.strip()]:
|
||||
self._add_path_to_list(self.duplicate_blacklist_list, p)
|
||||
|
||||
@@ -1286,11 +1302,15 @@ class SettingsDialog(QDialog):
|
||||
APP_CONFIG["viewer_wheel_speed"] = self.viewer_wheel_spin.value()
|
||||
APP_CONFIG["duplicate_method"] = self.duplicate_method_combo.currentData()
|
||||
APP_CONFIG["duplicate_threshold"] = self.duplicate_threshold_slider.value()
|
||||
APP_CONFIG["default_delete_to_trash"] = self.default_delete_to_trash_checkbox.isChecked()
|
||||
APP_CONFIG["duplicate_confirm_delete"] = self.duplicate_confirm_delete_checkbox.isChecked()
|
||||
wl_paths = [self.duplicate_whitelist_list.item(i).text() for i in range(self.duplicate_whitelist_list.count())]
|
||||
APP_CONFIG["default_delete_to_trash"] = \
|
||||
self.default_delete_to_trash_checkbox.isChecked()
|
||||
APP_CONFIG["duplicate_confirm_delete"] = \
|
||||
self.duplicate_confirm_delete_checkbox.isChecked()
|
||||
wl_paths = [self.duplicate_whitelist_list.item(i).text()
|
||||
for i in range(self.duplicate_whitelist_list.count())]
|
||||
APP_CONFIG["duplicate_whitelist"] = ",".join(wl_paths)
|
||||
bl_paths = [self.duplicate_blacklist_list.item(i).text() for i in range(self.duplicate_blacklist_list.count())]
|
||||
bl_paths = [self.duplicate_blacklist_list.item(i).text()
|
||||
for i in range(self.duplicate_blacklist_list.count())]
|
||||
APP_CONFIG["duplicate_blacklist"] = ",".join(bl_paths)
|
||||
|
||||
APP_CONFIG["viewer_auto_resize_window"] = \
|
||||
@@ -1381,7 +1401,8 @@ class SettingsDialog(QDialog):
|
||||
item = QListWidgetItem(path)
|
||||
if not os.path.isdir(path):
|
||||
item.setForeground(QColor("red"))
|
||||
item.setToolTip(f"Warning: Path not found or is not a directory: {path}")
|
||||
item.setToolTip(
|
||||
UITexts.SETTINGS_PATH_NOT_FOUND_WARNING.format(path))
|
||||
list_widget.addItem(item)
|
||||
|
||||
def add_whitelist_path(self):
|
||||
@@ -1393,7 +1414,8 @@ class SettingsDialog(QDialog):
|
||||
def remove_whitelist_path(self):
|
||||
"""Removes the selected folders from the whitelist list."""
|
||||
for item in self.duplicate_whitelist_list.selectedItems():
|
||||
self.duplicate_whitelist_list.takeItem(self.duplicate_whitelist_list.row(item))
|
||||
self.duplicate_whitelist_list.takeItem(
|
||||
self.duplicate_whitelist_list.row(item))
|
||||
|
||||
def add_blacklist_path(self):
|
||||
"""Opens a directory dialog to add a folder to the blacklist."""
|
||||
@@ -1404,10 +1426,12 @@ class SettingsDialog(QDialog):
|
||||
def remove_blacklist_path(self):
|
||||
"""Removes the selected folders from the blacklist list."""
|
||||
for item in self.duplicate_blacklist_list.selectedItems():
|
||||
self.duplicate_blacklist_list.takeItem(self.duplicate_blacklist_list.row(item))
|
||||
self.duplicate_blacklist_list.takeItem(
|
||||
self.duplicate_blacklist_list.row(item))
|
||||
|
||||
def update_duplicate_scan_count(self):
|
||||
"""Calculates and updates the count of images in whitelist/blacklist using a background thread."""
|
||||
"""Calculates and updates the count of images in whitelist/blacklist
|
||||
using a background thread."""
|
||||
if self.counter_thread and self.counter_thread.isRunning():
|
||||
self.counter_thread.stop()
|
||||
self.counter_thread.wait()
|
||||
@@ -1417,17 +1441,23 @@ class SettingsDialog(QDialog):
|
||||
blacklist_paths = [self.duplicate_blacklist_list.item(i).text()
|
||||
for i in range(self.duplicate_blacklist_list.count())]
|
||||
|
||||
whitelist = [os.path.abspath(os.path.expanduser(p.strip())) for p in whitelist_paths if p.strip()]
|
||||
blacklist = {os.path.abspath(os.path.expanduser(p.strip())) for p in blacklist_paths if p.strip()}
|
||||
whitelist = [os.path.abspath(os.path.expanduser(p.strip()))
|
||||
for p in whitelist_paths if p.strip()]
|
||||
blacklist = {os.path.abspath(os.path.expanduser(p.strip()))
|
||||
for p in blacklist_paths if p.strip()}
|
||||
|
||||
if not whitelist:
|
||||
self.duplicate_scan_count_label.setText(UITexts.SETTINGS_DUPLICATE_SCAN_COUNT_LABEL.format(0))
|
||||
self.duplicate_scan_count_label.setText(
|
||||
UITexts.SETTINGS_DUPLICATE_SCAN_COUNT_LABEL.format(0))
|
||||
self.duplicate_scan_progress.hide()
|
||||
return
|
||||
|
||||
self.duplicate_scan_progress.show()
|
||||
self.counter_thread = DuplicateFileCounter(whitelist, blacklist, IMAGE_EXTENSIONS)
|
||||
self.counter_thread = DuplicateFileCounter(
|
||||
whitelist, blacklist, IMAGE_EXTENSIONS)
|
||||
self.counter_thread.count_updated.connect(
|
||||
lambda c: self.duplicate_scan_count_label.setText(UITexts.SETTINGS_DUPLICATE_SCAN_COUNT_LABEL.format(c)))
|
||||
self.counter_thread.finished.connect(lambda: self.duplicate_scan_progress.hide())
|
||||
lambda c: self.duplicate_scan_count_label.setText(
|
||||
UITexts.SETTINGS_DUPLICATE_SCAN_COUNT_LABEL.format(c)))
|
||||
self.counter_thread.finished.connect(
|
||||
lambda: self.duplicate_scan_progress.hide())
|
||||
self.counter_thread.start()
|
||||
|
||||
Reference in New Issue
Block a user