Fixed thumbnail reload on metadata change
This commit is contained in:
@@ -1037,6 +1037,7 @@ class MainWindow(QMainWindow):
|
||||
self._group_info_cache = {}
|
||||
self._visible_paths_cache = None # Cache for visible image paths
|
||||
self._path_to_model_index = {}
|
||||
self._paths_being_modified_by_app = set() # For ignoring FS events
|
||||
|
||||
# Keep references to open viewers to manage their lifecycle
|
||||
self.viewers = []
|
||||
@@ -1349,6 +1350,10 @@ class MainWindow(QMainWindow):
|
||||
self.fs_watcher.monitoring_status_changed.connect(
|
||||
self.on_fs_watcher_status_changed)
|
||||
|
||||
# Set up callback for metadata managers
|
||||
from metadatamanager import set_app_modified_callback
|
||||
set_app_modified_callback(self._mark_path_as_app_modified)
|
||||
|
||||
# Batching for file creation events
|
||||
self._fs_created_queue = set()
|
||||
self._fs_created_timer = QTimer(self)
|
||||
@@ -4863,22 +4868,52 @@ class MainWindow(QMainWindow):
|
||||
if path not in self._known_paths:
|
||||
return # Not a file we're tracking
|
||||
|
||||
# Invalidate cache and trigger a refresh of its metadata and thumbnail
|
||||
self.cache.invalidate_path(path)
|
||||
# If this modification was initiated by the app, ignore it
|
||||
if path in self._paths_being_modified_by_app:
|
||||
return
|
||||
|
||||
# Re-read metadata and thumbnail
|
||||
res = load_common_metadata(path)
|
||||
mtime = os.path.getmtime(path)
|
||||
stat_res = os.stat(path)
|
||||
inode = stat_res.st_ino
|
||||
dev = stat_res.st_dev
|
||||
# External modification: check if it's metadata-only or content change
|
||||
try:
|
||||
new_stat = os.stat(path)
|
||||
new_mtime = new_stat.st_mtime
|
||||
new_size = new_stat.st_size
|
||||
|
||||
# Update internal data and model
|
||||
self._update_internal_data(path, mtime=mtime, tags=res.tags, rating=res.rating,
|
||||
inode=inode, dev=dev)
|
||||
self.proxy_model.add_to_cache(path, res.tags)
|
||||
self.rebuild_view()
|
||||
self.status_lbl.setText(f"File modified: {os.path.basename(path)}")
|
||||
# Find old data from internal list
|
||||
old_item_data = next((item for item in self.found_items_data if item[0] == path), None)
|
||||
old_mtime = old_item_data[2] if old_item_data else 0
|
||||
old_size = os.path.getsize(path) if old_item_data else 0 # Re-read size from disk for comparison
|
||||
|
||||
if new_size == old_size and new_mtime != old_mtime:
|
||||
# Likely metadata-only change (size unchanged, mtime changed)
|
||||
res = load_common_metadata(path)
|
||||
self._update_internal_data(path, mtime=new_mtime, tags=res.tags, rating=res.rating,
|
||||
inode=new_stat.st_ino, dev=new_stat.st_dev)
|
||||
self.proxy_model.add_to_cache(path, res.tags)
|
||||
self.thumbnail_view.viewport().update() # Force repaint
|
||||
self.status_lbl.setText(f"Metadata updated: {os.path.basename(path)}")
|
||||
else:
|
||||
# Content or size changed, invalidate thumbnail and rebuild view
|
||||
self.cache.invalidate_path(path)
|
||||
res = load_common_metadata(path) # Re-read metadata as well
|
||||
self._update_internal_data(path, mtime=new_mtime, tags=res.tags, rating=res.rating,
|
||||
inode=new_stat.st_ino, dev=new_stat.st_dev)
|
||||
self.proxy_model.add_to_cache(path, res.tags)
|
||||
self.rebuild_view()
|
||||
self.status_lbl.setText(f"File modified: {os.path.basename(path)}")
|
||||
except Exception:
|
||||
# Fallback to full refresh if error occurs
|
||||
self.refresh_content()
|
||||
|
||||
def _mark_path_as_app_modified(self, path):
|
||||
"""Marks a path as being modified by the application to ignore FS events."""
|
||||
abs_path = os.path.abspath(path)
|
||||
parent_path = os.path.dirname(abs_path)
|
||||
self._paths_being_modified_by_app.add(abs_path)
|
||||
self._paths_being_modified_by_app.add(parent_path)
|
||||
|
||||
# Schedule removal after a delay to allow all FS events to propagate
|
||||
QTimer.singleShot(1000, lambda: self._paths_being_modified_by_app.discard(abs_path))
|
||||
QTimer.singleShot(1000, lambda: self._paths_being_modified_by_app.discard(parent_path))
|
||||
|
||||
def on_fs_watcher_status_changed(self, is_monitoring):
|
||||
"""Updates the UI indicator for the FileSystemWatcher."""
|
||||
@@ -4893,6 +4928,9 @@ class MainWindow(QMainWindow):
|
||||
"""Handles a directory being modified (e.g., new subfolder, mass changes)."""
|
||||
path = os.path.abspath(path)
|
||||
|
||||
if path in self._paths_being_modified_by_app:
|
||||
return
|
||||
|
||||
# Trigger a debounced full refresh. This is useful for syncing large
|
||||
# external changes (bulk operations, directory deletions) that are
|
||||
# more robustly handled by a full scan than incremental updates.
|
||||
|
||||
Reference in New Issue
Block a user