Skip to content

Commit a7ff835

Browse files
authored
Allow boolean customization
Idea per @ObscureNightingale to allow customization of boolean values, both by default, and per window.
1 parent c29a4eb commit a7ff835

File tree

1 file changed

+66
-28
lines changed

1 file changed

+66
-28
lines changed

Scripts/plistwindow.py

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)