@@ -221,6 +221,7 @@ def __init__(self, controller, root, **kw):
221221 self .saving = False
222222 self .last_data = None
223223 self .last_int = None
224+ self .last_bool = None
224225 # self.xcode_data = self.controller.xcode_data # keep <data>xxxx</data> in one line when true
225226 # self.sort_dict = self.controller.sort_dict # Preserve key ordering in dictionaries when loading/saving
226227 self .menu_code = u"\u21D5 "
@@ -271,11 +272,6 @@ def __init__(self, controller, root, **kw):
271272 self .root_type_menu = tk .Menu (self , tearoff = 0 )
272273 self .root_type_menu .add_command (label = "Dictionary" , command = lambda :self .change_type (self .menu_code + " Dictionary" ))
273274 self .root_type_menu .add_command (label = "Array" , command = lambda :self .change_type (self .menu_code + " Array" ))
274-
275- # Set up the boolean selection menu
276- self .bool_menu = tk .Menu (self , tearoff = 0 )
277- self .bool_menu .add_command (label = "True" , command = lambda :self .set_bool ("True" ))
278- self .bool_menu .add_command (label = "False" , command = lambda :self .set_bool ("False" ))
279275
280276 self .style = ttk .Style ()
281277 # Treeview theming is horribly broken in Windows for whatever reasons...
@@ -382,26 +378,32 @@ def __init__(self, controller, root, **kw):
382378
383379 # Create our type/data view
384380 self .display_frame = tk .Frame (self ,height = 20 )
385- for x in (2 ,4 ,6 ):
381+ for x in (2 ,4 ,6 , 8 ):
386382 self .display_frame .columnconfigure (x ,weight = 1 )
387383 pt_label = tk .Label (self .display_frame ,text = "Plist Type:" )
388384 dt_label = tk .Label (self .display_frame ,text = "Display Data as:" )
389385 in_label = tk .Label (self .display_frame ,text = "Display Integers as:" )
386+ bl_label = tk .Label (self .display_frame ,text = "Display Booleans as:" )
390387 self .plist_type_string = tk .StringVar (self .display_frame )
391- self .plist_type_menu = tk .OptionMenu (self .display_frame , self .plist_type_string , "XML" , "Binary" , command = self .change_plist_type )
392- self .plist_type_string .set ("XML" )
388+ self .plist_type_menu = tk .OptionMenu (self .display_frame , self .plist_type_string , * self . controller . allowed_types , command = self .change_plist_type )
389+ self .plist_type_string .set (self . controller . allowed_types [ 0 ] )
393390 self .data_type_string = tk .StringVar (self .display_frame )
394- self .data_type_menu = tk .OptionMenu (self .display_frame , self .data_type_string , "Hex" , "Base64" , command = self .change_data_type )
395- self .data_type_string .set ("Hex" )
391+ self .data_type_menu = tk .OptionMenu (self .display_frame , self .data_type_string , * self . controller . allowed_data , command = self .change_data_type )
392+ self .data_type_string .set (self . controller . allowed_data [ 0 ] )
396393 self .int_type_string = tk .StringVar (self .display_frame )
397- self .int_type_menu = tk .OptionMenu (self .display_frame , self .int_type_string , "Decimal" ,"Hex" , command = self .change_int_type )
398- self .int_type_string .set ("Decimal" )
394+ self .int_type_menu = tk .OptionMenu (self .display_frame , self .int_type_string , * self .controller .allowed_int , command = self .change_int_type )
395+ self .int_type_string .set (self .controller .allowed_int [0 ])
396+ self .bool_type_string = tk .StringVar (self .display_frame )
397+ self .bool_type_menu = tk .OptionMenu (self .display_frame , self .bool_type_string , * self .controller .allowed_bool , command = self .change_bool_type )
398+ self .bool_type_string .set (self .controller .allowed_bool [0 ])
399399 pt_label .grid (row = 1 ,column = 1 ,padx = 10 ,pady = (0 ,5 ),sticky = "w" )
400400 dt_label .grid (row = 1 ,column = 3 ,padx = 10 ,pady = (0 ,5 ),sticky = "w" )
401401 in_label .grid (row = 1 ,column = 5 ,padx = 10 ,pady = (0 ,5 ),sticky = "w" )
402+ bl_label .grid (row = 1 ,column = 7 ,padx = 10 ,pady = (0 ,5 ),sticky = "w" )
402403 self .plist_type_menu .grid (row = 1 ,column = 2 ,padx = 10 ,pady = 10 ,sticky = "we" )
403404 self .data_type_menu .grid (row = 1 ,column = 4 ,padx = 10 ,pady = 10 ,sticky = "we" )
404405 self .int_type_menu .grid (row = 1 ,column = 6 ,padx = 10 ,pady = 10 ,sticky = "we" )
406+ self .bool_type_menu .grid (row = 1 ,column = 8 ,padx = 10 ,pady = 10 ,sticky = "we" )
405407
406408 # Create our find/replace view
407409 self .find_frame = tk .Frame (self ,height = 20 )
@@ -481,6 +483,28 @@ def change_int_type(self, value):
481483 self .change_int_display (value )
482484 self .last_int = value
483485
486+ def change_bool_type (self , value ):
487+ self .change_bool_display (value )
488+ self .last_bool = value
489+
490+ def b_true (self ,lower = False ):
491+ return self .bool_type_string .get ().split ("/" )[0 ].lower () if lower else self .bool_type_string .get ().split ("/" )[0 ]
492+
493+ def all_b_true (self ,lower = False ):
494+ return [x .split ("/" )[0 ].lower () if lower else x .split ("/" )[0 ] for x in self .controller .allowed_bool ]
495+
496+ def b_false (self ,lower = False ):
497+ return self .bool_type_string .get ().split ("/" )[- 1 ].lower () if lower else self .bool_type_string .get ().split ("/" )[- 1 ]
498+
499+ def all_b_false (self ,lower = False ):
500+ return [x .split ("/" )[- 1 ].lower () if lower else x .split ("/" )[- 1 ] for x in self .controller .allowed_bool ]
501+
502+ def all_b (self ,lower = False ):
503+ b = []
504+ for x in self .controller .allowed_bool :
505+ b .extend ([a .lower () if lower else a for a in x .split ("/" )])
506+ return b
507+
484508 def change_find_type (self , value ):
485509 self .find_type = value
486510
@@ -538,9 +562,9 @@ def qualify_value(self, value, value_type):
538562 value = "0x" + value
539563 value = str (value )
540564 elif value_type == "boolean" :
541- if not value .lower () in ( "true" , "false" ):
542- return (False ,"Invalid Boolean Data" ,"Booleans can only be True/False." )
543- value = "True" if value .lower () == "true" else "False"
565+ if not value .lower () in self . all_b ( lower = True ):
566+ return (False ,"Invalid Boolean Data" ,"Booleans can only be {}." . format ( ", " . join ( self . all_b ())) )
567+ value = self . b_true () if value .lower () in self . all_b_true ( lower = True ) else self . b_false ()
544568 return (True ,value )
545569
546570 def draw_frames (self , event = None , changed = None ):
@@ -1326,16 +1350,15 @@ def clicked(self, event = None):
13261350 # Mouse down in a valid node
13271351 self .clicked_drag = True
13281352
1329- def change_int_display (self , new_display = "Decimal" ):
1353+ def change_int_display (self , new_display = "Decimal" ):
13301354 if new_display == self .last_int : return
13311355 self .int_type_string .set (new_display [0 ].upper ()+ new_display [1 :])
13321356 nodes = self .iter_nodes (False )
1333- removedlist = []
13341357 for node in nodes :
1335- values = self .get_padded_values (node ,3 )
13361358 t = self .get_check_type (node ).lower ()
1337- value = values [1 ]
13381359 if t == "number" :
1360+ values = self .get_padded_values (node ,3 )
1361+ value = values [1 ]
13391362 if new_display .lower () == "hex" :
13401363 try :
13411364 value = int (value )
@@ -1348,13 +1371,25 @@ def change_int_display(self, new_display = "Decimal"):
13481371 values [1 ] = value
13491372 self ._tree .item (node ,values = values )
13501373
1351- def change_data_display (self , new_display = "Hex" ):
1374+ def change_bool_display (self ,new_display = "True/False" ):
1375+ if new_display == self .last_bool : return
1376+ self .bool_type_string .set (new_display )
1377+ nodes = self .iter_nodes (False )
1378+ on ,off = new_display .split ("/" )
1379+ on_list = [x .split ("/" )[0 ] for x in self .controller .allowed_bool ]
1380+ for node in nodes :
1381+ values = self .get_padded_values (node ,3 )
1382+ t = self .get_check_type (node ).lower ()
1383+ if t == "boolean" :
1384+ values [1 ] = on if values [1 ] in on_list else off
1385+ self ._tree .item (node ,values = values )
1386+
1387+ def change_data_display (self ,new_display = "Hex" ):
13521388 if new_display == self .last_data : return
13531389 self .data_type_string .set (new_display [0 ].upper ()+ new_display [1 :])
13541390 # This will change how data is displayed - we do this by converting all our existing
13551391 # data values to bytes, then reconverting and displaying appropriately
13561392 nodes = self .iter_nodes (False )
1357- removedlist = []
13581393 for node in nodes :
13591394 values = self .get_padded_values (node ,3 )
13601395 t = self .get_check_type (node ).lower ()
@@ -1661,7 +1696,7 @@ def strip_disabled(self, event=None):
16611696 values = self .get_padded_values (node , 3 )
16621697 value = values [1 ]
16631698 check_type = self .get_check_type (node ).lower ()
1664- if check_type == "boolean" and (name == "enabled" and value == "False" ) or (name == "disabled" and value == "True" ):
1699+ if check_type == "boolean" and (name == "enabled" and value == self . b_false ()) or (name == "disabled" and value == self . b_true () ):
16651700 # Found one, remove its parent
16661701 rem_node = self ._tree .parent (node )
16671702 if root in (node , rem_node ):
@@ -2011,7 +2046,7 @@ def get_value_from_node(self,node=""):
20112046 elif check_type == "array" :
20122047 value = []
20132048 elif check_type == "boolean" :
2014- value = True if values [1 ].lower () == "true" else False
2049+ value = True if values [1 ].lower () in self . all_b_true ( lower = True ) else False
20152050 elif check_type == "number" :
20162051 if self .int_type_string .get ().lower () == "hex" and value .lower ().startswith ("0x" ):
20172052 try :
@@ -2269,7 +2304,7 @@ def change_type(self, value, cell = None):
22692304 if value .lower () == "number" :
22702305 values [1 ] = "0" if self .int_type_string .get ().lower () == "decimal" else "0x00"
22712306 elif value .lower () == "boolean" :
2272- values [1 ] = "True"
2307+ values [1 ] = self . b_true ()
22732308 elif value .lower () == "array" :
22742309 self ._tree .item (cell ,open = True )
22752310 values [1 ] = "0 children"
@@ -2662,7 +2697,6 @@ def on_double_click(self, event):
26622697 # Get the actual text
26632698 index = int (column .replace ("#" ,"" ))
26642699 try :
2665- # t = self._tree.item(rowid,"values")[0]
26662700 t = self .get_check_type (rowid )
26672701 except :
26682702 t = ""
@@ -2684,11 +2718,16 @@ def on_double_click(self, event):
26842718 # Can't edit the "value" directly - should only show the number of children
26852719 return 'break'
26862720 elif t .lower () == "boolean" :
2721+ # Set up the boolean selection menu
2722+ print (self .b_true (),self .b_false ())
2723+ bool_menu = tk .Menu (self , tearoff = 0 )
2724+ bool_menu .add_command (label = self .b_true (), command = lambda :self .set_bool (self .b_true ()))
2725+ bool_menu .add_command (label = self .b_false (), command = lambda :self .set_bool (self .b_false ()))
26872726 # Bool change
26882727 try :
2689- self . bool_menu .tk_popup (event .x_root , event .y_root , 0 )
2728+ bool_menu .tk_popup (event .x_root , event .y_root , 0 )
26902729 finally :
2691- self . bool_menu .grab_release ()
2730+ bool_menu .grab_release ()
26922731 return 'break'
26932732 if index == 0 :
26942733 if pt .lower () == "array" :
@@ -2704,7 +2743,6 @@ def on_double_click(self, event):
27042743 if index == 2 and t .lower () == "data" :
27052744 # Special formatting of hex values
27062745 text = text .replace ("<" ,"" ).replace (">" ,"" )
2707- cell = self ._tree .item ("" if not len (self ._tree .selection ()) else self ._tree .selection ()[0 ])
27082746 # place Entry popup properly
27092747 self .entry_popup = EntryPopup (self ._tree , self , text , tv_item , column )
27102748 self .entry_popup .place ( x = x , y = y + pady , anchor = "w" , width = width )
0 commit comments