@@ -775,14 +775,15 @@ def get_context_menu(self, menu):
775775 """
776776 return self ._context_menu .get (menu )
777777
778- def _deserialize_context_menu (self , menu , menu_data ):
778+ def _deserialize_context_menu (self , menu , menu_data , anchor_path = None ):
779779 """
780780 Populate context menu from a dictionary.
781781
782782 Args:
783783 menu (NodeGraphQt.NodeGraphMenu or NodeGraphQt.NodesMenu):
784784 parent context menu.
785785 menu_data (list[dict] or dict): serialized menu data.
786+ anchor_path (str or None): directory to interpret file paths relative to (optional)
786787 """
787788 if not menu :
788789 raise ValueError ('No context menu named: "{}"' .format (menu ))
@@ -792,6 +793,10 @@ def _deserialize_context_menu(self, menu, menu_data):
792793
793794 nodes_menu = self .get_context_menu ('nodes' )
794795
796+ anchor = Path (anchor_path ).resolve ()
797+ if anchor .is_file ():
798+ anchor = anchor .parent
799+
795800 def build_menu_command (menu , data ):
796801 """
797802 Create menu command from serialized data.
@@ -801,14 +806,16 @@ def build_menu_command(menu, data):
801806 menu object.
802807 data (dict): serialized menu command data.
803808 """
804- full_path = os .path .abspath (data ['file' ])
805- base_dir , file_name = os .path .split (full_path )
806- base_name = os .path .basename (base_dir )
807- file_name , _ = file_name .split ('.' )
809+ func_path = Path (data ['file' ])
810+ if not func_path .is_absolute ():
811+ func_path = anchor .joinpath (func_path )
812+
813+ base_name = func_path .parent .name
814+ file_name = func_path .stem
808815
809816 mod_name = '{}.{}' .format (base_name , file_name )
810817
811- spec = importlib .util .spec_from_file_location (mod_name , full_path )
818+ spec = importlib .util .spec_from_file_location (mod_name , func_path )
812819 mod = importlib .util .module_from_spec (spec )
813820 sys .modules [mod_name ] = mod
814821 spec .loader .exec_module (mod )
@@ -832,12 +839,12 @@ def build_menu_command(menu, data):
832839 elif item_type == 'menu' :
833840 sub_menu = menu .add_menu (menu_data ['label' ])
834841 items = menu_data .get ('items' , [])
835- self ._deserialize_context_menu (sub_menu , items )
842+ self ._deserialize_context_menu (sub_menu , items , anchor_path )
836843 elif isinstance (menu_data , list ):
837844 for item_data in menu_data :
838- self ._deserialize_context_menu (menu , item_data )
845+ self ._deserialize_context_menu (menu , item_data , anchor_path )
839846
840- def set_context_menu (self , menu_name , data ):
847+ def set_context_menu (self , menu_name , data , anchor_path = None ):
841848 """
842849 Populate a context menu from serialized data.
843850
@@ -875,11 +882,12 @@ def run_test(graph):
875882 Args:
876883 menu_name (str): name of the parent context menu to populate under.
877884 data (dict): serialized menu data.
885+ anchor_path (str or None): directory to interpret file paths relative to (optional)
878886 """
879887 context_menu = self .get_context_menu (menu_name )
880- self ._deserialize_context_menu (context_menu , data )
888+ self ._deserialize_context_menu (context_menu , data , anchor_path )
881889
882- def set_context_menu_from_file (self , file_path , menu = None ):
890+ def set_context_menu_from_file (self , file_path , menu = 'graph' ):
883891 """
884892 Populate a context menu from a serialized json file.
885893
@@ -892,16 +900,16 @@ def set_context_menu_from_file(self, file_path, menu=None):
892900 menu (str): name of the parent context menu to populate under.
893901 file_path (str): serialized menu commands json file.
894902 """
895- file_path = os . path . abspath (file_path )
903+ file = Path (file_path ). resolve ( )
896904
897905 menu = menu or 'graph'
898- if not os . path . isfile ( file_path ):
899- raise IOError ('file doesn\' t exists : "{}"' .format (file_path ))
906+ if not file . is_file ( ):
907+ raise IOError ('file doesn\' t exist : "{}"' .format (file ))
900908
901- with open (file_path ) as f :
909+ with file . open () as f :
902910 data = json .load (f )
903911 context_menu = self .get_context_menu (menu )
904- self ._deserialize_context_menu (context_menu , data )
912+ self ._deserialize_context_menu (context_menu , data , file )
905913
906914 def disable_context_menu (self , disabled = True , name = 'all' ):
907915 """
0 commit comments