# *********************************************************************** # TreeControl with drag and drop, RM-menu, etc # based on CT.CustomTreeCtrl # # License: freeware, under the terms of the BSD-license # Copyright (C) 2008 Stef Mientki # mailto:S.Mientki@ru.nl # # 0 : dataline = dataline [:-1] treefile.write ( line + self.GetItemText ( item ) + '=' + dataline+'\n' ) if self.HasChildren ( item ) : self._Enum_Tree_2_IniFile ( treefile, item, line + self.GetItemText ( item ) + '~' ) # treefile, item, line + self.GetItemText ( item ) + ',' ) item = self.GetNextSibling ( item ) # ***************************************************************** # Transports all parameters from the TREE to the INIFILE. # ***************************************************************** def Tree_2_IniFile ( self, ini_filename, ext = 'tree' ) : # inifile doesn't accept double key-values, # therefor we use normal text file fne, fe = os.path.splitext ( ini_filename ) treefile = open ( fne + '.' + ext, 'w') MainNode = self.root MainNode, cookie = self.GetFirstChild ( MainNode ) while MainNode : # Store the expansion of the mainnode state = self.IsItemChecked ( MainNode ) + 2*self.IsExpanded ( MainNode ) treefile.write ( '[' + self.GetItemText ( MainNode ) + '=' + str ( state ) + '\n' ) self._Enum_Tree_2_IniFile ( treefile, MainNode ) MainNode = self.GetNextSibling ( MainNode ) treefile.close() # ***************************************************************** # ***************************************************************** def IniFile_2_Tree ( self, ini_filename, ext = 'tree' ) : fne, fe = os.path.splitext ( ini_filename ) filename = fne + '.'+ ext #'.tree' if File_Exists ( filename ) : # ***************************************************************** # parse the inifile to create the tree # **************************************************************** treefile = open ( filename, 'r') lines = treefile.readlines () treefile.close () Lines_2_Tree ( lines ) # ***************************************************************** # ***************************************************************** def Lines_2_Tree ( self, lines ) : Expand = [] N = 0 for r in lines : if r: print ' lOPII',r r = r.rstrip ("\n\r") # remove CR, LF # split at the last "=" if r.find ('=') > 0 : #key, val = r.split('=') key, val = r.rsplit ( '=', 1 ) else : key = r val = '' # newer version uses '~' instead of ',' #if ( val.find ('~') >= 0 ) or ( key.find ('~') >=0 ): key = key.split ( '~' ) val = val.split ( '~' ) #else : # key = key.split ( ',' ) # val = val.split ( ',' ) if len ( val ) < 2 : val.append ( -1 ) if len ( val ) < 3 : val.append ( -1 ) if key[0][0] == '[': node_name = key[0][1:] MainNode = self.AppendItem ( self.root, node_name ) val[1] = 15 val[2] = 16 self.SetPyData ( MainNode, val ) self.SetItemImage ( MainNode, int( val[1] ), CT.TreeItemIcon_Normal ) self.SetItemImage ( MainNode, int( val[2] ), CT.TreeItemIcon_Expanded ) # set the expansion Mainnode that just has finished if len(Expand) > 0 : nod, exp = Expand[0] if exp: self.Expand ( nod ) Expand = [] print val Expand.append ( (MainNode, bool ( int(val[0]) & 2 )) ) N = 0 node = NODE = MainNode else : # keep track of nesting if len( key ) == N : nod, exp = Expand.pop() if exp: self.Expand ( nod ) elif len( key ) > N : NODE = node N += 1 elif len( key ) < N : for i in range ( N - len(key) + 1 ): nod, exp = Expand.pop() if exp: self.Expand (nod) for i in range ( N - len(key)): NODE = NODE.GetParent() N = len ( key ) node = self.AppendItem ( NODE, key [-1] ) self.SetPyData ( node, val ) self.SetItemImage ( node, int( val[1] ), CT.TreeItemIcon_Normal ) self.SetItemImage ( node, int( val[2] ), CT.TreeItemIcon_Expanded ) Expand.append ( ( node, bool(int(val[0]) & 2) )) # set the expansion last Mainnode that just has finished # SMALL BUG: if the last element a node with children, # it will never be expanded ??? if len(Expand) > 0 : nod, exp = Expand[0] if exp: self.Expand ( nod ) # *********************************************************************** # *********************************************************************** # A simple form to test the control # *********************************************************************** class Simple_Test_Form ( wx.MiniFrame ): def __init__ ( self, ini = None ): # restore position and size self.ini = ini if ini : ini.Section = 'Test' pos = ini.Read ( 'Pos' , ( 50, 50 ) ) size = ini.Read ( 'Size' , ( 500, 300 ) ) wx.MiniFrame.__init__( self, None, -1, 'Test PyLab Works GUI Control', size = size, pos = pos, style = wx.DEFAULT_FRAME_STYLE ) # ***************************************************************** Splitter = wx.SplitterWindow ( self ) # Create the control to be tested and read old settings self.Tree = Custom_TreeCtrl_Base ( Splitter ) self.Tree.On_Icon_Click = self.On_Icon_Click if ini: self.Tree.IniFile_2_Tree ( ini.filename ) self.Editor = wx.TextCtrl ( Splitter, -1, "Here iscontrol.\n\n" "The quied over the lazy dog...", size=(200, 100), style = wx.TE_MULTILINE | wx.TE_PROCESS_ENTER | wx.NO_3D | wx.NO_BORDER) Splitter.SplitVertically ( self.Tree, self.Editor ) # ***************************************************************** self. Bind ( wx.EVT_CLOSE, self.OnCloseWindow ) self. Bind ( CT.EVT_TREE_BEGIN_DRAG, self.OnBeginDrag ) self.Tree.Bind ( CT.EVT_TREE_END_DRAG, self.OnEndDrag ) Splitter.Bind ( wx.EVT_SPLITTER_DCLICK, self._Block_This ) def _Block_This ( self, event ) : event.Veto () # ************************************************************* # Change the icon if clicked on it # ************************************************************* def On_Icon_Click ( self, item ) : print ' JOEPIE...', self.Tree.GetItemImage(item) if self.Tree.GetItemImage ( item ) == 80 : Icon = 83 else : Icon = 80 self.Tree.SetItemImage ( item, Icon, CT.TreeItemIcon_Normal ) self.Tree.SetItemImage ( item, Icon, CT.TreeItemIcon_Expanded ) # ***************************************************************** # You can block the start of a drag event # ***************************************************************** def OnBeginDrag ( self, event ) : #event.Veto() pass # ***************************************************************** # You can block the end of a drag event # NOTE: the binding must be "self.Tree.Bind" # ***************************************************************** def OnEndDrag ( self, event ) : event.Skip() def OnCloseWindow ( self, event ) : self.Tree.Tree_2_IniFile ( self.ini.filename ) event.Skip () # *********************************************************************** # *********************************************************************** # demo program # *********************************************************************** if __name__ == '__main__': app = wx.PySimpleApp () ini = inifile ( 'test_My_Custom_TreeCtrl.cfg' ) frame = Simple_Test_Form (ini = ini) frame.Show ( True ) app.MainLoop () ini.Close () # ***********************************************************************