<s> """<STR_LIT>""" <EOL> from Tkinter import * <EOL> from MultiCall import MC_SHIFT <EOL> import AutoComplete <EOL> HIDE_VIRTUAL_EVENT_NAME = "<STR_LIT>" <EOL> HIDE_SEQUENCES = ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> KEYPRESS_VIRTUAL_EVENT_NAME = "<STR_LIT>" <EOL> KEYPRESS_SEQUENCES = ( "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" ) <EOL> KEYRELEASE_VIRTUAL_EVENT_NAME = "<STR_LIT>" <EOL> KEYRELEASE_SEQUENCE = "<STR_LIT>" <EOL> LISTUPDATE_SEQUENCE = "<STR_LIT>" <EOL> WINCONFIG_SEQUENCE = "<STR_LIT>" <EOL> DOUBLECLICK_SEQUENCE = "<STR_LIT>" <EOL> class AutoCompleteWindow : <EOL> def __init__ ( self , widget ) : <EOL> self . widget = widget <EOL> self . autocompletewindow = self . listbox = self . scrollbar = None <EOL> self . origselforeground = self . origselbackground = None <EOL> self . completions = None <EOL> self . morecompletions = None <EOL> self . mode = None <EOL> self . start = None <EOL> self . startindex = None <EOL> self . lasttypedstart = None <EOL> self . userwantswindow = None <EOL> self . hideid = self . keypressid = self . listupdateid = self . winconfigid = self . keyreleaseid = self . doubleclickid = None <EOL> self . lastkey_was_tab = False <EOL> def _change_start ( self , newstart ) : <EOL> min_len = min ( len ( self . start ) , len ( newstart ) ) <EOL> i = <NUM_LIT:0> <EOL> while i < min_len and self . start [ i ] == newstart [ i ] : <EOL> i += <NUM_LIT:1> <EOL> if i < len ( self . start ) : <EOL> self . widget . delete ( "<STR_LIT>" % ( self . startindex , i ) , <EOL> "<STR_LIT>" % ( self . startindex , len ( self . start ) ) ) <EOL> if i < len ( newstart ) : <EOL> self . widget . insert ( "<STR_LIT>" % ( self . startindex , i ) , <EOL> newstart [ i : ] ) <EOL> self . start = newstart <EOL> def _binary_search ( self , s ) : <EOL> """<STR_LIT>""" <EOL> i = <NUM_LIT:0> ; j = len ( self . completions ) <EOL> while j > i : <EOL> m = ( i + j ) // <NUM_LIT:2> <EOL> if self . completions [ m ] >= s : <EOL> j = m <EOL> else : <EOL> i = m + <NUM_LIT:1> <EOL> return min ( i , len ( self . completions ) - <NUM_LIT:1> ) <EOL> def _complete_string ( self , s ) : <EOL> """<STR_LIT>""" <EOL> first = self . _binary_search ( s ) <EOL> if self . completions [ first ] [ : len ( s ) ] != s : <EOL> return s <EOL> i = first + <NUM_LIT:1> <EOL> j = len ( self . completions ) <EOL> while j > i : <EOL> m = ( i + j ) // <NUM_LIT:2> <EOL> if self . completions [ m ] [ : len ( s ) ] != s : <EOL> j = m <EOL> else : <EOL> i = m + <NUM_LIT:1> <EOL> last = i - <NUM_LIT:1> <EOL> if first == last : <EOL> return self . completions [ first ] <EOL> first_comp = self . completions [ first ] <EOL> last_comp = self . completions [ last ] <EOL> min_len = min ( len ( first_comp ) , len ( last_comp ) ) <EOL> i = len ( s ) <EOL> while i < min_len and first_comp [ i ] == last_comp [ i ] : <EOL> i += <NUM_LIT:1> <EOL> return first_comp [ : i ] <EOL> def _selection_changed ( self ) : <EOL> """<STR_LIT>""" <EOL> cursel = int ( self . listbox . curselection ( ) [ <NUM_LIT:0> ] ) <EOL> self . listbox . see ( cursel ) <EOL> lts = self . lasttypedstart <EOL> selstart = self . completions [ cursel ] <EOL> if self . _binary_search ( lts ) == cursel : <EOL> newstart = lts <EOL> else : <EOL> min_len = min ( len ( lts ) , len ( selstart ) ) <EOL> i = <NUM_LIT:0> <EOL> while i < min_len and lts [ i ] == selstart [ i ] : <EOL> i += <NUM_LIT:1> <EOL> newstart = selstart [ : i ] <EOL> self . _change_start ( newstart ) <EOL> if self . completions [ cursel ] [ : len ( self . start ) ] == self . start : <EOL> self . listbox . configure ( selectbackground = self . origselbackground , <EOL> selectforeground = self . origselforeground ) <EOL> else : <EOL> self . listbox . configure ( selectbackground = self . listbox . cget ( "<STR_LIT>" ) , <EOL> selectforeground = self . listbox . cget ( "<STR_LIT>" ) ) <EOL> if self . morecompletions : <EOL> self . completions = self . morecompletions <EOL> self . morecompletions = None <EOL> self . listbox . delete ( <NUM_LIT:0> , END ) <EOL> for item in self . completions : <EOL> self . listbox . insert ( END , item ) <EOL> self . listbox . select_set ( self . _binary_search ( self . start ) ) <EOL> self . _selection_changed ( ) <EOL> def show_window ( self , comp_lists , index , complete , mode , userWantsWin ) : <EOL> """<STR_LIT>""" <EOL> self . completions , self . morecompletions = comp_lists <EOL> self . mode = mode <EOL> self . startindex = self . widget . index ( index ) <EOL> self . start = self . widget . get ( self . startindex , "<STR_LIT>" ) <EOL> if complete : <EOL> completed = self . _complete_string ( self . start ) <EOL> self . _change_start ( completed ) <EOL> i = self . _binary_search ( completed ) <EOL> if self . completions [ i ] == completed and ( i == len ( self . completions ) - <NUM_LIT:1> or <EOL> self . completions [ i + <NUM_LIT:1> ] [ : len ( completed ) ] != completed ) : <EOL> return <EOL> self . userwantswindow = userWantsWin <EOL> self . lasttypedstart = self . start <EOL> self . autocompletewindow = acw = Toplevel ( self . widget ) <EOL> acw . wm_geometry ( "<STR_LIT>" ) <EOL> acw . wm_overrideredirect ( <NUM_LIT:1> ) <EOL> try : <EOL> acw . tk . call ( "<STR_LIT>" , "<STR_LIT>" , acw . _w , <EOL> "<STR_LIT>" , "<STR_LIT>" ) <EOL> except TclError : <EOL> pass <EOL> self . scrollbar = scrollbar = Scrollbar ( acw , orient = VERTICAL ) <EOL> self . listbox = listbox = Listbox ( acw , yscrollcommand = scrollbar . set , <EOL> exportselection = False , bg = "<STR_LIT>" ) <EOL> for item in self . completions : <EOL> listbox . insert ( END , item ) <EOL> self . origselforeground = listbox . cget ( "<STR_LIT>" ) <EOL> self . origselbackground = listbox . cget ( "<STR_LIT>" ) <EOL> scrollbar . config ( command = listbox . yview ) <EOL> scrollbar . pack ( side = RIGHT , fill = Y ) <EOL> listbox . pack ( side = LEFT , fill = BOTH , expand = True ) <EOL> self . listbox . select_set ( self . _binary_search ( self . start ) ) <EOL> self . _selection_changed ( ) <EOL> self . hideid = self . widget . bind ( HIDE_VIRTUAL_EVENT_NAME , <EOL> self . hide_event ) <EOL> for seq in HIDE_SEQUENCES : <EOL> self . widget . event_add ( HIDE_VIRTUAL_EVENT_NAME , seq ) <EOL> self . keypressid = self . widget . bind ( KEYPRESS_VIRTUAL_EVENT_NAME , <EOL> self . keypress_event ) <EOL> for seq in KEYPRESS_SEQUENCES : <EOL> self . widget . event_add ( KEYPRESS_VIRTUAL_EVENT_NAME , seq ) <EOL> self . keyreleaseid = self . widget . bind ( KEYRELEASE_VIRTUAL_EVENT_NAME , <EOL> self . keyrelease_event ) <EOL> self . widget . event_add ( KEYRELEASE_VIRTUAL_EVENT_NAME , KEYRELEASE_SEQUENCE ) <EOL> self . listupdateid = listbox . bind ( LISTUPDATE_SEQUENCE , <EOL> self . listselect_event ) <EOL> self . winconfigid = acw . bind ( WINCONFIG_SEQUENCE , self . winconfig_event ) <EOL> self . doubleclickid = listbox . bind ( DOUBLECLICK_SEQUENCE , <EOL> self . doubleclick_event ) <EOL> def winconfig_event ( self , event ) : <EOL> if not self . is_active ( ) : <EOL> return <EOL> text = self . widget <EOL> text . see ( self . startindex ) <EOL> x , y , cx , cy = text . bbox ( self . startindex ) <EOL> acw = self . autocompletewindow <EOL> acw_width , acw_height = acw . winfo_width ( ) , acw . winfo_height ( ) <EOL> text_width , text_height = text . winfo_width ( ) , text . winfo_height ( ) <EOL> new_x = text . winfo_rootx ( ) + min ( x , max ( <NUM_LIT:0> , text_width - acw_width ) ) <EOL> new_y = text . winfo_rooty ( ) + y <EOL> if ( text_height - ( y + cy ) >= acw_height <EOL> or y < acw_height ) : <EOL> new_y += cy <EOL> else : <EOL> new_y -= acw_height <EOL> acw . wm_geometry ( "<STR_LIT>" % ( new_x , new_y ) ) <EOL> def hide_event ( self , event ) : <EOL> if not self . is_active ( ) : <EOL> return <EOL> self . hide_window ( ) <EOL> def listselect_event ( self , event ) : <EOL> if not self . is_active ( ) : <EOL> return <EOL> self . userwantswindow = True <EOL> cursel = int ( self . listbox . curselection ( ) [ <NUM_LIT:0> ] ) <EOL> self . _change_start ( self . completions [ cursel ] ) <EOL> def doubleclick_event ( self , event ) : <EOL> cursel = int ( self . listbox . curselection ( ) [ <NUM_LIT:0> ] ) <EOL> self . _change_start ( self . completions [ cursel ] ) <EOL> self . hide_window ( ) <EOL> def keypress_event ( self , event ) : <EOL> if not self . is_active ( ) : <EOL> return <EOL> keysym = event . keysym <EOL> if hasattr ( event , "<STR_LIT>" ) : <EOL> state = event . mc_state <EOL> else : <EOL> state = <NUM_LIT:0> <EOL> if keysym != "<STR_LIT>" : <EOL> self . lastkey_was_tab = False <EOL> if ( len ( keysym ) == <NUM_LIT:1> or keysym in ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> or ( self . mode == AutoComplete . COMPLETE_FILES and keysym in <EOL> ( "<STR_LIT>" , "<STR_LIT>" ) ) ) and not ( state & ~ MC_SHIFT ) : <EOL> if len ( keysym ) == <NUM_LIT:1> : <EOL> self . _change_start ( self . start + keysym ) <EOL> elif keysym == "<STR_LIT>" : <EOL> self . _change_start ( self . start + '<STR_LIT:_>' ) <EOL> elif keysym == "<STR_LIT>" : <EOL> self . _change_start ( self . start + '<STR_LIT:.>' ) <EOL> elif keysym == "<STR_LIT>" : <EOL> self . _change_start ( self . start + '<STR_LIT:->' ) <EOL> else : <EOL> if len ( self . start ) == <NUM_LIT:0> : <EOL> self . hide_window ( ) <EOL> return <EOL> self . _change_start ( self . start [ : - <NUM_LIT:1> ] ) <EOL> self . lasttypedstart = self . start <EOL> self . listbox . select_clear ( <NUM_LIT:0> , int ( self . listbox . curselection ( ) [ <NUM_LIT:0> ] ) ) <EOL> self . listbox . select_set ( self . _binary_search ( self . start ) ) <EOL> self . _selection_changed ( ) <EOL> return "<STR_LIT>" <EOL> elif keysym == "<STR_LIT>" : <EOL> self . hide_window ( ) <EOL> return <EOL> elif ( self . mode == AutoComplete . COMPLETE_ATTRIBUTES and keysym in <EOL> ( "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" ) ) or ( self . mode == AutoComplete . COMPLETE_FILES and keysym in <EOL> ( "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ) ) and not ( state & ~ MC_SHIFT ) : <EOL> cursel = int ( self . listbox . curselection ( ) [ <NUM_LIT:0> ] ) <EOL> if self . completions [ cursel ] [ : len ( self . start ) ] == self . start and ( self . mode == AutoComplete . COMPLETE_ATTRIBUTES or self . start ) : <EOL> self . _change_start ( self . completions [ cursel ] ) <EOL> self . hide_window ( ) <EOL> return <EOL> elif keysym in ( "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ) and not state : <EOL> self . userwantswindow = True <EOL> cursel = int ( self . listbox . curselection ( ) [ <NUM_LIT:0> ] ) <EOL> if keysym == "<STR_LIT>" : <EOL> newsel = <NUM_LIT:0> <EOL> elif keysym == "<STR_LIT>" : <EOL> newsel = len ( self . completions ) - <NUM_LIT:1> <EOL> elif keysym in ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> jump = self . listbox . nearest ( self . listbox . winfo_height ( ) ) - self . listbox . nearest ( <NUM_LIT:0> ) <EOL> if keysym == "<STR_LIT>" : <EOL> newsel = max ( <NUM_LIT:0> , cursel - jump ) <EOL> else : <EOL> assert keysym == "<STR_LIT>" <EOL> newsel = min ( len ( self . completions ) - <NUM_LIT:1> , cursel + jump ) <EOL> elif keysym == "<STR_LIT>" : <EOL> newsel = max ( <NUM_LIT:0> , cursel - <NUM_LIT:1> ) <EOL> else : <EOL> assert keysym == "<STR_LIT>" <EOL> newsel = min ( len ( self . completions ) - <NUM_LIT:1> , cursel + <NUM_LIT:1> ) <EOL> self . listbox . select_clear ( cursel ) <EOL> self . listbox . select_set ( newsel ) <EOL> self . _selection_changed ( ) <EOL> self . _change_start ( self . completions [ newsel ] ) <EOL> return "<STR_LIT>" <EOL> elif ( keysym == "<STR_LIT>" and not state ) : <EOL> if self . lastkey_was_tab : <EOL> cursel = int ( self . listbox . curselection ( ) [ <NUM_LIT:0> ] ) <EOL> self . _change_start ( self . completions [ cursel ] ) <EOL> self . hide_window ( ) <EOL> return "<STR_LIT>" <EOL> else : <EOL> self . userwantswindow = True <EOL> self . lastkey_was_tab = True <EOL> return <EOL> elif reduce ( lambda x , y : x or y , <EOL> [ keysym . find ( s ) != - <NUM_LIT:1> for s in ( "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT:Meta>" , "<STR_LIT>" , "<STR_LIT>" ) <EOL> ] ) : <EOL> return <EOL> else : <EOL> self . hide_window ( ) <EOL> return <EOL> def keyrelease_event ( self , event ) : <EOL> if not self . is_active ( ) : <EOL> return <EOL> if self . widget . index ( "<STR_LIT>" ) != self . widget . index ( "<STR_LIT>" % ( self . startindex , len ( self . start ) ) ) : <EOL> self . hide_window ( ) <EOL> def is_active ( self ) : <EOL> return self . autocompletewindow is not None <EOL> def complete ( self ) : <EOL> self . _change_start ( self . _complete_string ( self . start ) ) <EOL> def hide_window ( self ) : <EOL> if not self . is_active ( ) : <EOL> return <EOL> for seq in HIDE_SEQUENCES : <EOL> self . widget . event_delete ( HIDE_VIRTUAL_EVENT_NAME , seq ) <EOL> self . widget . unbind ( HIDE_VIRTUAL_EVENT_NAME , self . hideid ) <EOL> self . hideid = None <EOL> for seq in KEYPRESS_SEQUENCES : <EOL> self . widget . event_delete ( KEYPRESS_VIRTUAL_EVENT_NAME , seq ) <EOL> self . widget . unbind ( KEYPRESS_VIRTUAL_EVENT_NAME , self . keypressid ) <EOL> self . keypressid = None <EOL> self . widget . event_delete ( KEYRELEASE_VIRTUAL_EVENT_NAME , <EOL> KEYRELEASE_SEQUENCE ) <EOL> self . widget . unbind ( KEYRELEASE_VIRTUAL_EVENT_NAME , self . keyreleaseid ) <EOL> self . keyreleaseid = None <EOL> self . listbox . unbind ( LISTUPDATE_SEQUENCE , self . listupdateid ) <EOL> self . listupdateid = None <EOL> self . autocompletewindow . unbind ( WINCONFIG_SEQUENCE , self . winconfigid ) <EOL> self . winconfigid = None <EOL> self . scrollbar . destroy ( ) <EOL> self . scrollbar = None <EOL> self . listbox . destroy ( ) <EOL> self . listbox = None <EOL> self . autocompletewindow . destroy ( ) <EOL> self . autocompletewindow = None </s>
