Skip to content

Commit 76bffaf

Browse files
committed
Add new signal for updating a file (such as editing a title), that results in the files_model updating the thumbnail, updating the name, and/or updating the tags.
1 parent 660b902 commit 76bffaf

File tree

4 files changed

+76
-38
lines changed

4 files changed

+76
-38
lines changed

src/windows/main_window.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ class MainWindow(QMainWindow, updates.UpdateWatcher):
101101
InsertKeyframe = pyqtSignal(object)
102102
OpenProjectSignal = pyqtSignal(str)
103103
ThumbnailUpdated = pyqtSignal(str)
104+
FileUpdated = pyqtSignal(str)
104105

105106
# Docks are closable, movable and floatable
106107
docks_frozen = False
@@ -409,8 +410,8 @@ def actionEditTitle_trigger(self, event):
409410
# Run the dialog event loop - blocking interaction on this window during that time
410411
result = win.exec_()
411412

412-
# Refresh files views
413-
self.refreshFilesSignal.emit()
413+
# Update file thumbnail
414+
self.FileUpdated.emit(selected_file_id)
414415

415416
# Force update of clips
416417
clips = Clip.filter(file_id=selected_file_id)
@@ -422,6 +423,9 @@ def actionEditTitle_trigger(self, event):
422423
# Emit thumbnail update signal (to update timeline thumb image)
423424
self.ThumbnailUpdated.emit(c.id)
424425

426+
# Update preview
427+
self.refreshFrameSignal.emit()
428+
425429
def actionDuplicateTitle_trigger(self, event):
426430

427431
file_path = None
@@ -538,6 +542,9 @@ def open_project(self, file_path, clear_thumbnails=True):
538542
# Refresh files views
539543
self.refreshFilesSignal.emit()
540544

545+
# Refresh thumbnail
546+
self.refreshFrameSignal.emit()
547+
541548
# Load recent projects again
542549
self.load_recent_menu()
543550

src/windows/models/files_model.py

+58-15
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ def changed(self, action):
114114
elif action.type == "delete" and action.key[0].lower() == "files":
115115
# Don't clear the existing items if only deleting things
116116
self.update_model(clear=False, delete_file_id=action.key[1].get('id', ''))
117+
elif action.type == "update" and action.key[0].lower() == "files":
118+
# Do nothing for file updates
119+
pass
117120
else:
118121
# Clear existing items
119122
self.update_model(clear=True)
@@ -122,6 +125,8 @@ def update_model(self, clear=True, delete_file_id=None):
122125
log.info("updating files model.")
123126
app = get_app()
124127

128+
self.ignore_updates = True
129+
125130
# Get window to check filters
126131
win = app.window
127132
_ = app._tr
@@ -139,10 +144,6 @@ def update_model(self, clear=True, delete_file_id=None):
139144
self.model_ids.pop(delete_file_id)
140145
break
141146

142-
# Skip updates (if needed)
143-
if self.ignore_update_signal:
144-
return
145-
146147
# Clear all items
147148
if clear:
148149
self.model_ids = {}
@@ -178,16 +179,8 @@ def update_model(self, clear=True, delete_file_id=None):
178179
fps_float = float(fps["num"]) / float(fps["den"])
179180
thumbnail_frame = round(float(file.data['start']) * fps_float) + 1
180181

181-
# Determine thumb path (default value... a guess)
182-
thumb_path = os.path.join(info.THUMBNAIL_PATH, "%s-%s.png" % (file.id, thumbnail_frame))
183-
184-
# Connect to thumbnail server and get image
185-
thumb_server_details = get_app().window.http_server_thread.server_address
186-
thumb_address = "http://%s:%s/thumbnails/%s/%s/path/" % (thumb_server_details[0], thumb_server_details[1], file.id, thumbnail_frame)
187-
r = get(thumb_address)
188-
if r.ok:
189-
# Update thumbnail path to real one
190-
thumb_path = r.text
182+
# Get thumb path
183+
thumb_path = self.get_thumb_path(file.id, thumbnail_frame)
191184
else:
192185
# Audio file
193186
thumb_path = os.path.join(info.PATH, "images", "AudioThumbnail.png")
@@ -250,9 +243,56 @@ def update_model(self, clear=True, delete_file_id=None):
250243
# Refresh view and filters (to hide or show this new item)
251244
get_app().window.resize_contents()
252245

246+
self.ignore_updates = False
247+
253248
# Emit signal when model is updated
254249
self.model.ModelRefreshed.emit()
255250

251+
def get_thumb_path(self, file_id, thumbnail_frame, clear_cache=False):
252+
"""Get thumbnail path by invoking HTTP thumbnail request"""
253+
254+
# Clear thumb cache (if requested)
255+
thumb_cache = ""
256+
if clear_cache:
257+
thumb_cache = "no-cache/"
258+
259+
# Connect to thumbnail server and get image
260+
thumb_server_details = get_app().window.http_server_thread.server_address
261+
thumb_address = "http://%s:%s/thumbnails/%s/%s/path/%s" % (
262+
thumb_server_details[0], thumb_server_details[1], file_id, thumbnail_frame, thumb_cache)
263+
r = get(thumb_address)
264+
if r.ok:
265+
# Update thumbnail path to real one
266+
return r.text
267+
else:
268+
return ''
269+
270+
def update_file_thumbnail(self, file_id):
271+
"""Update/re-generate the thumbnail of a specific file"""
272+
file = File.get(id=file_id)
273+
path, filename = os.path.split(file.data["path"])
274+
name = filename
275+
if "name" in file.data.keys():
276+
name = file.data["name"]
277+
278+
# Refresh thumbnail for updated file
279+
self.ignore_updates = True
280+
if file_id in self.model_ids:
281+
for row_num in range(self.model.rowCount()):
282+
id_index = self.model.index(row_num, 5)
283+
if file_id == self.model.data(id_index):
284+
# Update thumb for file
285+
thumb_index = self.model.index(row_num, 0)
286+
thumb_path = self.get_thumb_path(file_id, 1, clear_cache=True)
287+
item = self.model.itemFromIndex(thumb_index)
288+
item.setIcon(QIcon(thumb_path))
289+
item.setText(name)
290+
291+
# Emit signal when model is updated
292+
self.model.ModelRefreshed.emit()
293+
break
294+
self.ignore_updates = False
295+
256296
def __init__(self, *args):
257297

258298
# Add self as listener to project data updates (undo/redo, as well as normal actions handled within this class all update the tree model)
@@ -263,7 +303,7 @@ def __init__(self, *args):
263303
self.model = FileStandardItemModel()
264304
self.model.setColumnCount(6)
265305
self.model_ids = {}
266-
self.ignore_update_signal = False
306+
self.ignore_updates = False
267307

268308
# Create proxy model (for sorting and filtering)
269309
self.proxy_model = FileFilterProxyModel()
@@ -272,3 +312,6 @@ def __init__(self, *args):
272312
self.proxy_model.setSortCaseSensitivity(Qt.CaseSensitive)
273313
self.proxy_model.setSourceModel(self.model)
274314
self.proxy_model.setSortLocaleAware(True)
315+
316+
# Connect signal
317+
app.window.FileUpdated.connect(self.update_file_thumbnail)

src/windows/views/files_listview.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -312,13 +312,6 @@ def currentChanged(self, selected, deselected):
312312
def resize_contents(self):
313313
pass
314314

315-
def prepare_for_delete(self):
316-
"""Remove signal handlers and prepare for deletion"""
317-
try:
318-
self.files_model.model.ModelRefreshed.disconnect()
319-
except Exception:
320-
pass
321-
322315
def __init__(self, model):
323316
# Invoke parent init
324317
QListView.__init__(self)
@@ -348,6 +341,7 @@ def __init__(self, model):
348341
self.setWordWrap(False)
349342
self.setTextElideMode(Qt.ElideRight)
350343
self.setStyleSheet('QListView::item { padding-top: 2px; }')
344+
self.files_model.model.ModelRefreshed.connect(self.refresh_view)
351345

352346
# Load initial files model data
353347
self.files_model.update_model()

src/windows/views/files_treeview.py

+8-14
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,9 @@ def currentChanged(self, selected, deselected):
326326

327327
def value_updated(self, item):
328328
""" Name or tags updated """
329+
if self.files_model.ignore_updates:
330+
return
331+
329332
# Get translation method
330333
_ = get_app()._tr
331334

@@ -336,31 +339,22 @@ def value_updated(self, item):
336339

337340
# Get file object and update friendly name and tags attribute
338341
f = File.get(id=file_id)
339-
if name != f.data["path"]:
342+
if name and name != os.path.split(f.data["path"])[-1]:
340343
f.data["name"] = name
341344
else:
342-
f.data["name"] = ""
345+
f.data["name"] = os.path.split(f.data["path"])[-1]
346+
343347
if "tags" in f.data.keys():
344348
if tags != f.data["tags"]:
345349
f.data["tags"] = tags
346350
elif tags:
347351
f.data["tags"] = tags
348352

349-
# Tell file model to ignore updates (since this treeview will already be updated)
350-
self.files_model.ignore_update_signal = True
351-
352353
# Save File
353354
f.save()
354355

355-
# Re-enable updates
356-
self.files_model.ignore_update_signal = False
357-
358-
def prepare_for_delete(self):
359-
"""Remove signal handlers and prepare for deletion"""
360-
try:
361-
self.files_model.model.ModelRefreshed.disconnect()
362-
except:
363-
pass
356+
# Update file thumbnail
357+
self.win.FileUpdated.emit(file_id)
364358

365359
def __init__(self, model):
366360
# Invoke parent init

0 commit comments

Comments
 (0)