11import tkinter
2+ import base64
23from tkinter import ttk
34from pathlib import Path
45import tkinter .filedialog
56import tkinter .messagebox
67import tkinter .ttk
7- from pyBjson import convertBjsonToJson
8- import json
8+ from pyBjson import BJSONFile
99import threading
1010from functools import partial
1111import sys , os , argparse
12- from pyBjson .utils import uint_to_bytes , int_to_bytes , float_to_bytes
1312
14- VERSION = "v1.0.2-dev"
13+ VERSION = "v1.1.0"
14+
15+ def encode_key64 (key : str ):
16+ return base64 .urlsafe_b64encode (key .encode ("utf-8" )).decode ("utf-8" )
17+
18+ def decode_key64 (key : str ):
19+ return base64 .urlsafe_b64decode (key .encode ("utf-8" )).decode ("utf-8" )
1520
1621def getBjsonContent (fp : str | Path ):
1722 try :
@@ -20,55 +25,57 @@ def getBjsonContent(fp: str|Path):
2025 tkinter .messagebox .showerror ("Unable to load file" , f"Could not open the specified file. Error: { e } " )
2126 return data
2227
23- def addDictToTree (tree : ttk .Treeview , root : str , key : str , data : dict ):
28+ def addDictToTree (tree : ttk .Treeview , root : str , key : str , data : dict , path : str ):
2429 if root == "" :
2530 opened = True
31+ path = "root"
2632 else :
2733 opened = False
28- sub_node = tree .insert (root , "end" , text = key , open = opened , values = ["Object" ])
34+ sub_node = tree .insert (root , "end" , text = key , open = opened , values = ["Object" ], iid = path )
2935 for key in data :
3036 if type (data [key ]) == dict :
31- addDictToTree (tree , sub_node , key , data [key ])
37+ addDictToTree (tree , sub_node , key , data [key ], f" { path } / { encode_key64 ( key ) } " )
3238 elif type (data [key ]) == list :
33- addListToTree (tree , sub_node , key , data [key ])
39+ addListToTree (tree , sub_node , key , data [key ], f" { path } / { encode_key64 ( key ) } " )
3440 else :
35- addSingleElementToTree (tree , sub_node , key , data [key ])
41+ addSingleElementToTree (tree , sub_node , key , data [key ], f" { path } / { encode_key64 ( key ) } " )
3642
37- def addListToTree (tree : ttk .Treeview , root : str , key : str , data : list ):
43+ def addListToTree (tree : ttk .Treeview , root : str , key : str , data : list , path : str ):
3844 if root == "" :
3945 opened = True
46+ path = "root"
4047 else :
4148 opened = False
42- sub_node = tree .insert (root , "end" , text = key , open = opened , values = ["Array" ])
43- for element in data :
49+ sub_node = tree .insert (root , "end" , text = key , open = opened , values = ["Array" ], iid = path )
50+ for idx , element in enumerate ( data ) :
4451 if type (element ) == dict :
45- addDictToTree (tree , sub_node , "Object" , element )
52+ addDictToTree (tree , sub_node , "Object" , element , f" { path } / { idx } " )
4653 elif type (element ) == list :
47- addListToTree (tree , sub_node , "Array" , element )
54+ addListToTree (tree , sub_node , "Array" , element , f" { path } / { idx } " )
4855 elif type (element ) == int or type (element ) == float :
49- addSingleElementToTree (tree , sub_node , "Number" , element )
56+ addSingleElementToTree (tree , sub_node , "Number" , element , f" { path } / { idx } " )
5057 elif type (element ) == str :
51- addSingleElementToTree (tree , sub_node , "String" , element )
58+ addSingleElementToTree (tree , sub_node , "String" , element , f" { path } / { idx } " )
5259 elif type (element ) == bool :
53- addSingleElementToTree (tree , sub_node , "Boolean" , element )
60+ addSingleElementToTree (tree , sub_node , "Boolean" , element , f" { path } / { idx } " )
5461 else :
55- addSingleElementToTree (tree , sub_node , "null" , None )
62+ addSingleElementToTree (tree , sub_node , "null" , None , f" { path } / { idx } " )
5663
57- def addSingleElementToTree (tree : ttk .Treeview , root : str , key : str , data ):
64+ def addSingleElementToTree (tree : ttk .Treeview , root : str , key : str , data , path : str ):
5865 if type (data ) == int or type (data ) == float :
59- tree .insert (root , "end" , text = key , values = ["Number" , data ])
66+ tree .insert (root , "end" , text = key , values = ["Number" , data ], iid = path )
6067 elif type (data ) == str :
61- tree .insert (root , "end" , text = key , values = ["String" , data ])
68+ tree .insert (root , "end" , text = key , values = ["String" , data ], iid = path )
6269 elif type (data ) == bool :
63- tree .insert (root , "end" , text = key , values = ["Boolean" , data ])
70+ tree .insert (root , "end" , text = key , values = ["Boolean" , data ], iid = path )
6471 else :
65- tree .insert (root , "end" , text = key , values = ["null" , "null" ])
72+ tree .insert (root , "end" , text = key , values = ["null" , "null" ], iid = path )
6673
6774def populate_tree (tree : ttk .Treeview , data : dict | list ):
6875 if type (data ) == dict :
69- addDictToTree (tree , "" , "root" , data )
76+ addDictToTree (tree , "" , "root" , data , "" )
7077 elif type (data ) == list :
71- addListToTree (tree , "" , "root" , data )
78+ addListToTree (tree , "" , "root" , data , "" )
7279
7380def loadFileDataFromBjson (root , tree : ttk .Treeview , fp : str | Path ):
7481 loading_label = tkinter .Label (root , text = "Loading file..." )
@@ -77,6 +84,7 @@ def loadFileDataFromBjson(root, tree: ttk.Treeview, fp: str|Path):
7784 bjson_dict = getBjsonContent (fp )
7885
7986 if bjson_dict :
87+ print ("Populating tree" )
8088 populate_tree (tree , bjson_dict )
8189 if not hasattr (tree , 'icons' ):
8290 tree .icons = {}
@@ -90,6 +98,7 @@ def loadFileDataFromBjson(root, tree: ttk.Treeview, fp: str|Path):
9098 tree .grid (row = 0 , column = 0 , sticky = "wesn" )
9199 inputPath = Path (fp )
92100 root .title (f"MC3DS BJSON Editor - { inputPath .name } " )
101+ root .bjson_dict = bjson_dict
93102 except :
94103 pass
95104
@@ -193,6 +202,7 @@ def __init__(self, fp = None):
193202 self .lastValue = None
194203 self .filePath = fp
195204 self .selectedItem = None
205+ self .bjson_dict : dict | list
196206
197207 if fp != None :
198208 threading .Thread (target = partial (loadFileDataFromBjson , self , self .tree , fp )).start ()
@@ -220,15 +230,30 @@ def registerChange(self):
220230 if (type (newValue ) == type (self .lastValue )) or ((type (newValue ) == int or type (newValue ) == float ) and dataType == "Number" ):
221231 if self .selectedItem :
222232 self .tree .item (self .selectedItem , values = [dataType , newValue ])
223- print ("Change registered" )
224- self .saved = False
233+ keys = self .selectedItem .split ("/" )
234+ if len (keys ) > 1 :
235+ d = self .bjson_dict
236+ for key in keys [1 :- 1 ]:
237+ if type (d ) == dict :
238+ d = d [decode_key64 (key )]
239+ elif type (d ) == list :
240+ d = d [int (key )]
241+ if dataType == "Boolean" :
242+ newValue = True if newValue == "true" else False
243+ if type (d ) == dict :
244+ d [decode_key64 (keys [- 1 ])] = newValue
245+ elif type (d ) == list :
246+ d [int (keys [- 1 ])] = newValue
247+ print ("Change registered" )
248+ self .saved = False
225249 else :
226250 tkinter .messagebox .showwarning (title = "Invalid value" , message = "The value entered is not valid for this instance" )
227251
228252 def saveChanges (self ):
229253 if type (self .filePath ) == str :
230254 # TODO: Convert treeview to json
231- fileContent = []
255+ bjsonNewData = BJSONFile ().fromPython (self .bjson_dict )
256+ fileContent = bjsonNewData .getData ()
232257 outputPath = tkinter .filedialog .asksaveasfilename (defaultextension = ".bjson" , filetypes = [("BJSON Files" , ".bjson" )])
233258 if outputPath != "" :
234259 with open (outputPath , "wb" ) as f :
@@ -267,19 +292,35 @@ def itemSelected(self, event):
267292 item = self .tree .item (selected_item )
268293 self .selectedItem = selected_item
269294 record = item ['values' ]
295+ itemType = record [0 ]
296+ # Search stored value
297+ keys = self .selectedItem .split ("/" )
298+ if len (keys ) > 1 :
299+ d = self .bjson_dict
300+
301+ for key in keys [1 :- 1 ]:
302+ if (type (d ) == dict ):
303+ d = d [decode_key64 (key )]
304+ elif (type (d ) == list ):
305+ d = d [int (key )]
306+ if (type (d ) == dict ):
307+ itemValue = d [decode_key64 (keys [- 1 ])]
308+ elif (type (d ) == list ):
309+ itemValue = d [int (keys [- 1 ])]
310+
270311 self .dataTypeStringVar .set (record [0 ])
271312 if len (record ) > 1 :
272- if record [ 0 ] != "Boolean" :
273- self .valueStringVar .set (record [ 1 ] )
274- self .lastValue = record [ 1 ]
313+ if itemType != "Boolean" :
314+ self .valueStringVar .set (str ( itemValue ) )
315+ self .lastValue = itemValue
275316 else :
276- if record [ 2 ] == True :
317+ if itemValue == True :
277318 self .valueStringVar .set ("true" )
278319 self .lastValue = "true"
279320 else :
280321 self .valueStringVar .set ("false" )
281322 self .lastValue = "false"
282- if record [ 0 ] != "String" and record [ 0 ] != "null" :
323+ if itemType != "null" :
283324 self .valueEntry .configure (state = "normal" )
284325 self .saveButton .configure (state = "normal" )
285326 else :
0 commit comments