From 2e433db1e800748760eb91dcfcbdf251f15cd22e Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Thu, 15 Feb 2024 15:16:48 -0600 Subject: [PATCH 1/5] Fixing bug when copying effects from 1 clip to another clip. We were copying the "id" from the first clip, instead of generating a new one. --- src/windows/views/webview.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/windows/views/webview.py b/src/windows/views/webview.py index 1006b1a64..6abde81eb 100644 --- a/src/windows/views/webview.py +++ b/src/windows/views/webview.py @@ -1596,7 +1596,9 @@ def Copy_Triggered(self, action, clip_ids, tran_ids): elif action == MENU_COPY_KEYFRAMES_VOLUME: self.copy_clipboard[clip_id]['volume'] = clip.data['volume'] elif action == MENU_COPY_EFFECTS: - self.copy_clipboard[clip_id]['effects'] = clip.data['effects'] + self.copy_clipboard[clip_id]['effects'] = [{k: (get_app().project.generate_id() if k == 'id' else v) + for k, v in effect.items()} for effect in clip.data['effects']] + # Loop through transition objects for tran_id in tran_ids: From cc313ba605c2520747c5661d1c46b95d1d75e97e Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Thu, 15 Feb 2024 16:01:14 -0600 Subject: [PATCH 2/5] Fixing bug when copying effects from 1 clip to another clip. We were copying the "id" from the first clip, instead of generating a new one. Take 2.. generating ID on Paste instead of copy. --- src/windows/views/webview.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/windows/views/webview.py b/src/windows/views/webview.py index 6abde81eb..1d2f631dd 100644 --- a/src/windows/views/webview.py +++ b/src/windows/views/webview.py @@ -1596,8 +1596,7 @@ def Copy_Triggered(self, action, clip_ids, tran_ids): elif action == MENU_COPY_KEYFRAMES_VOLUME: self.copy_clipboard[clip_id]['volume'] = clip.data['volume'] elif action == MENU_COPY_EFFECTS: - self.copy_clipboard[clip_id]['effects'] = [{k: (get_app().project.generate_id() if k == 'id' else v) - for k, v in effect.items()} for effect in clip.data['effects']] + self.copy_clipboard[clip_id]['effects'] = clip.data['effects'] # Loop through transition objects @@ -1708,6 +1707,10 @@ def Paste_Triggered(self, action, position, layer_id, clip_ids, tran_ids): # Apply clipboard to clip (there should only be a single key in this dict) for k, v in self.copy_clipboard[list(self.copy_clipboard)[0]].items(): if k != 'id': + if k == 'effects': + # Update effect IDs + v = [{k: (get_app().project.generate_id() if k == 'id' else v) + for k, v in effect.items()} for effect in v] # Overwrite clips properties (which are in the clipboard) clip.data[k] = v From 6f2c96ed7b1546d825ca332ecd051c347145e832 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Thu, 15 Feb 2024 16:46:32 -0600 Subject: [PATCH 3/5] Also updating effect IDs when entire clips are pasted --- src/windows/views/webview.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/windows/views/webview.py b/src/windows/views/webview.py index 1d2f631dd..5175ea32a 100644 --- a/src/windows/views/webview.py +++ b/src/windows/views/webview.py @@ -1670,6 +1670,10 @@ def Paste_Triggered(self, action, position, layer_id, clip_ids, tran_ids): clip.type = 'insert' clip.data.pop('id') + # Update effect IDs + clip.data['effects'] = [{k: (get_app().project.generate_id() if k == 'id' else v) + for k, v in effect.items()} for effect in clip.data['effects']] + # Adjust the position and track clip.data['position'] += position_diff clip.data['layer'] += layer_diff From 8cb08f580032226dd0b3b045b43fcecf3365849c Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Thu, 15 Feb 2024 17:10:35 -0600 Subject: [PATCH 4/5] Removing Ctrl-C shortcut from main window UI file --- src/windows/ui/main-window.ui | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/windows/ui/main-window.ui b/src/windows/ui/main-window.ui index 123651991..7c7af845b 100644 --- a/src/windows/ui/main-window.ui +++ b/src/windows/ui/main-window.ui @@ -1731,9 +1731,6 @@ Insert Timestamp - - Ctrl+C - From 64c631735f70a1b8e027373ad041caf6ea0c4eb3 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Thu, 15 Feb 2024 17:11:33 -0600 Subject: [PATCH 5/5] Adding new copyAll and pasteAll methods, and connecting them to main window QShortcuts, to ensure the Webview does not eat our Ctrl+C/Ctrl+V keypress events. --- src/windows/main_window.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/windows/main_window.py b/src/windows/main_window.py index c73df81f7..3cbb5840a 100644 --- a/src/windows/main_window.py +++ b/src/windows/main_window.py @@ -3134,6 +3134,17 @@ def playToggle(self): """Handle play-pause-toggle keypress""" get_app().window.PlayPauseToggleSignal.emit() + def copyAll(self): + """Handle Copy QShortcut (selected clips / transitions)""" + self.timeline.Copy_Triggered(-1, self.selected_clips, self.selected_transitions) + + def pasteAll(self): + """Handle Paste QShortcut (at timeline position, same track as original clip)""" + fps = get_app().project.get("fps") + fps_float = float(fps["num"]) / float(fps["den"]) + playhead_position = float(self.preview_thread.current_frame - 1) / fps_float + self.timeline.Paste_Triggered(9, float(playhead_position), -1, [], []) + def eventFilter(self, obj, event): """Filter out certain QShortcuts - for example, arrow keys used in our files, transitions, effects, and emojis views.""" @@ -3442,4 +3453,6 @@ def __init__(self, *args): QShortcut(app.window.getShortcutByName("playToggle"), self, activated=self.playToggle, context=Qt.WindowShortcut) QShortcut(app.window.getShortcutByName("playToggle1"), self, activated=self.playToggle, context=Qt.WindowShortcut) QShortcut(app.window.getShortcutByName("playToggle2"), self, activated=self.playToggle, context=Qt.WindowShortcut) - QShortcut(app.window.getShortcutByName("playToggle3"), self, activated=self.playToggle, context=Qt.WindowShortcut) \ No newline at end of file + QShortcut(app.window.getShortcutByName("playToggle3"), self, activated=self.playToggle, context=Qt.WindowShortcut) + QShortcut(app.window.getShortcutByName("copyAll"), self, activated=self.copyAll, context=Qt.WindowShortcut) + QShortcut(app.window.getShortcutByName("pasteAll"), self, activated=self.pasteAll, context=Qt.WindowShortcut)