@@ -543,7 +543,7 @@ def ShowTimelineMenu(self, position, layer_number):
543
543
Paste_Clip = menu .addAction (_ ("Paste" ))
544
544
Paste_Clip .setShortcut (QKeySequence (self .window .getShortcutByName ("pasteAll" )))
545
545
Paste_Clip .triggered .connect (
546
- partial (self .Paste_Triggered , MenuCopy .PASTE , float ( position ), int ( layer_number ), [], [])
546
+ partial (self .Paste_Triggered , MenuCopy .PASTE , [], [])
547
547
)
548
548
549
549
# Show menu
@@ -637,7 +637,7 @@ def ShowClipMenu(self, clip_id=None):
637
637
if has_clipboard :
638
638
# Paste Menu (Only show if partial clipboard available)
639
639
Paste_Clip = menu .addAction (_ ("Paste" ))
640
- Paste_Clip .triggered .connect (partial (self .Paste_Triggered , MenuCopy .PASTE , 0.0 , 0 , clip_ids , []))
640
+ Paste_Clip .triggered .connect (partial (self .Paste_Triggered , MenuCopy .PASTE , clip_ids , []))
641
641
642
642
menu .addSeparator ()
643
643
@@ -1678,89 +1678,106 @@ def RemoveAllGaps_Triggered(self, found_start, layer_number):
1678
1678
# Clear transaction id
1679
1679
get_app ().updates .transaction_id = None
1680
1680
1681
- def Paste_Triggered (self , action , position , layer_id , clip_ids , tran_ids ):
1681
+ def Paste_Triggered (self , action , clip_ids , tran_ids ):
1682
1682
"""Callback for paste context menus"""
1683
1683
log .debug (action )
1684
1684
1685
- # Start transaction
1686
- tid = self .get_uuid ()
1687
- get_app ().updates .transaction_id = tid
1688
-
1689
- # Get clipboard
1690
- copied_object = ClipboardManager .from_mime (get_app ().clipboard ().mimeData ())
1691
- if not copied_object :
1692
- get_app ().updates .transaction_id = None
1693
- return
1694
-
1695
- print (f"Copied object found: { type (copied_object ).__name__ } " )
1696
-
1697
- # Adjust positions and layers for lists of objects
1698
- def adjust_positions_and_layers (objects , position , layer_id ):
1699
- left_most_position = min (obj .data ['position' ] for obj in objects )
1700
- top_most_layer = max (obj .data ['layer' ] for obj in objects )
1701
- position_diff = position - left_most_position
1702
- layer_diff = layer_id - top_most_layer if layer_id != - 1 else 0
1703
-
1704
- for obj in objects :
1705
- obj .type = 'insert'
1706
- obj .data .pop ('id' , None )
1707
- obj .id = None
1708
- if 'effects' in obj .data :
1709
- obj .data ['effects' ] = [
1710
- {k : (get_app ().project .generate_id () if k == 'id' else v ) for k , v in effect .items ()}
1711
- for effect in obj .data ['effects' ]
1712
- ]
1713
- obj .data ['position' ] += position_diff
1714
- obj .data ['layer' ] += layer_diff
1715
- obj .save ()
1716
-
1717
- # Apply clipboard data to target object, merging effects
1718
- def apply_clipboard_data (target_obj , clipboard_data , excluded_keys = None ):
1719
- excluded_keys = excluded_keys or []
1720
- for k , v in clipboard_data .items ():
1721
- if k in excluded_keys :
1722
- continue
1723
- if k == 'effects' and isinstance (v , list ):
1724
- existing_effects = target_obj .data .setdefault ('effects' , [])
1725
- effect_map = {effect ['class_name' ]: effect for effect in existing_effects }
1726
-
1727
- for effect in v :
1728
- effect_type = effect .get ('class_name' )
1729
- effect ['id' ] = get_app ().project .generate_id ()
1730
- if effect_type in effect_map :
1731
- effect_map [effect_type ].update (effect )
1732
- else :
1733
- existing_effects .append (effect )
1685
+ # Get global mouse position
1686
+ global_mouse_pos = QCursor .pos ()
1687
+ local_mouse_pos = self .mapFromGlobal (global_mouse_pos )
1734
1688
1735
- target_obj .data ['effects' ] = existing_effects
1736
- else :
1737
- target_obj .data [k ] = v
1738
- target_obj .save ()
1739
-
1740
- # If a single clip/transition is copied with no target, add to a list (for inserting)
1741
- if len (clip_ids + tran_ids ) == 0 and \
1742
- (isinstance (copied_object , Clip ) or isinstance (copied_object , Transition )):
1743
- copied_object = [copied_object ]
1689
+ # Callback function, to actually add the clip object
1690
+ def callback (self , clip_ids , tran_ids , callback_data ):
1691
+ position = callback_data .get ('position' , 0.0 )
1692
+ layer_id = callback_data .get ('track' , 0 )
1744
1693
1745
- # Handle list of objects (adjust positions and layers)
1746
- if isinstance ( copied_object , list ):
1747
- adjust_positions_and_layers ( copied_object , position , layer_id )
1694
+ # Start transaction
1695
+ tid = self . get_uuid ()
1696
+ get_app (). updates . transaction_id = tid
1748
1697
1749
- # Handle individual objects (Clip, Transition, Effect)
1750
- for clip_id in clip_ids :
1751
- clip = Clip .get (id = clip_id )
1752
- if clip and isinstance (copied_object , Clip ):
1753
- apply_clipboard_data (clip , copied_object .data , excluded_keys = ['id' , 'position' , 'layer' , 'start' , 'end' ])
1754
- if clip and isinstance (copied_object , Effect ):
1755
- apply_clipboard_data (clip , {"effects" : [copied_object .data ]}, excluded_keys = ['id' ])
1698
+ # Get clipboard
1699
+ copied_object = ClipboardManager .from_mime (get_app ().clipboard ().mimeData ())
1700
+ if not copied_object :
1701
+ get_app ().updates .transaction_id = None
1702
+ return
1756
1703
1757
- for tran_id in tran_ids :
1758
- tran = Transition .get (id = tran_id )
1759
- if tran and isinstance (copied_object , Transition ):
1760
- apply_clipboard_data (tran , copied_object .data , excluded_keys = ['id' , 'position' , 'layer' , 'start' , 'end' ])
1704
+ # Remove copied ids from targets
1705
+ if isinstance (copied_object , Clip ):
1706
+ clip_ids = [id for id in clip_ids if id != copied_object .id ]
1707
+ if isinstance (copied_object , Transition ):
1708
+ tran_ids = [id for id in tran_ids if id != copied_object .id ]
1709
+
1710
+ # Adjust positions and layers for lists of objects
1711
+ def adjust_positions_and_layers (objects , position , layer_id ):
1712
+ left_most_position = min (obj .data ['position' ] for obj in objects )
1713
+ top_most_layer = max (obj .data ['layer' ] for obj in objects )
1714
+ position_diff = position - left_most_position
1715
+ layer_diff = layer_id - top_most_layer if layer_id != - 1 else 0
1716
+
1717
+ for obj in objects :
1718
+ obj .type = 'insert'
1719
+ obj .data .pop ('id' , None )
1720
+ obj .id = None
1721
+ if 'effects' in obj .data :
1722
+ obj .data ['effects' ] = [
1723
+ {k : (get_app ().project .generate_id () if k == 'id' else v ) for k , v in effect .items ()}
1724
+ for effect in obj .data ['effects' ]
1725
+ ]
1726
+ obj .data ['position' ] += position_diff
1727
+ obj .data ['layer' ] += layer_diff
1728
+ obj .save ()
1729
+
1730
+ # Apply clipboard data to target object, merging effects
1731
+ def apply_clipboard_data (target_obj , clipboard_data , excluded_keys = None ):
1732
+ excluded_keys = excluded_keys or []
1733
+ for k , v in clipboard_data .items ():
1734
+ if k in excluded_keys :
1735
+ continue
1736
+ if k == 'effects' and isinstance (v , list ):
1737
+ existing_effects = target_obj .data .setdefault ('effects' , [])
1738
+ effect_map = {effect ['class_name' ]: effect for effect in existing_effects }
1739
+
1740
+ for effect in v :
1741
+ effect_type = effect .get ('class_name' )
1742
+ effect ['id' ] = get_app ().project .generate_id ()
1743
+ if effect_type in effect_map :
1744
+ effect_map [effect_type ].update (effect )
1745
+ else :
1746
+ existing_effects .append (effect )
1747
+
1748
+ target_obj .data ['effects' ] = existing_effects
1749
+ else :
1750
+ target_obj .data [k ] = v
1751
+ target_obj .save ()
1752
+
1753
+ # If a single clip/transition is copied with no target, add to a list (for inserting)
1754
+ if len (clip_ids + tran_ids ) == 0 and \
1755
+ (isinstance (copied_object , Clip ) or isinstance (copied_object , Transition )):
1756
+ copied_object = [copied_object ]
1757
+
1758
+ # Handle list of objects (adjust positions and layers)
1759
+ if isinstance (copied_object , list ):
1760
+ adjust_positions_and_layers (copied_object , position , layer_id )
1761
+
1762
+ # Handle individual objects (Clip, Transition, Effect)
1763
+ for clip_id in clip_ids :
1764
+ clip = Clip .get (id = clip_id )
1765
+ if clip and isinstance (copied_object , Clip ):
1766
+ apply_clipboard_data (clip , copied_object .data , excluded_keys = ['id' , 'position' , 'layer' , 'start' , 'end' ])
1767
+ if clip and isinstance (copied_object , Effect ):
1768
+ apply_clipboard_data (clip , {"effects" : [copied_object .data ]}, excluded_keys = ['id' ])
1769
+
1770
+ for tran_id in tran_ids :
1771
+ tran = Transition .get (id = tran_id )
1772
+ if tran and isinstance (copied_object , Transition ):
1773
+ apply_clipboard_data (tran , copied_object .data , excluded_keys = ['id' , 'position' , 'layer' , 'start' , 'end' ])
1774
+
1775
+ # End transaction
1776
+ get_app ().updates .transaction_id = None
1761
1777
1762
- # End transaction
1763
- get_app ().updates .transaction_id = None
1778
+ # Find position from javascript
1779
+ self .run_js (JS_SCOPE_SELECTOR + ".getJavaScriptPosition({}, {});"
1780
+ .format (local_mouse_pos .x (), local_mouse_pos .y ()), partial (callback , self , clip_ids , tran_ids ))
1764
1781
1765
1782
def Nudge_Triggered (self , action , clip_ids , tran_ids ):
1766
1783
"""Callback for clip nudges"""
@@ -2722,7 +2739,7 @@ def ShowTransitionMenu(self, tran_id=None):
2722
2739
if has_clipboard :
2723
2740
# Paste Menu (Only show when partial transition clipboard available)
2724
2741
Paste_Tran = menu .addAction (_ ("Paste" ))
2725
- Paste_Tran .triggered .connect (partial (self .Paste_Triggered , MenuCopy .PASTE , 0.0 , 0 , [], tran_ids ))
2742
+ Paste_Tran .triggered .connect (partial (self .Paste_Triggered , MenuCopy .PASTE , [], tran_ids ))
2726
2743
2727
2744
menu .addSeparator ()
2728
2745
0 commit comments