
    jjB              	      L   d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	m
Z
 ddlmZ dd	lmZ dd
lmZ ddlmZ ej&                  rddlmZmZ dZ G d de      Z G d deeej4                  eef               Z G d d      Z G d de      Z G d de
      Z G d de	      Zy)z
Urwid tree view

Features:
- custom selectable widgets for trees
- custom list walker for displaying widgets in a tree fashion
    )annotationsN   )Columns)
WHSettings)ListBox
ListWalker)Padding)Text)
WidgetWrap)SelectableIcon)HashableSequence)
ParentNodeTreeListBoxTreeNode
TreeWalker
TreeWidgetTreeWidgetErrorc                      e Zd Zy)r   N)__name__
__module____qualname__     _/home/ubuntu/.cache/pipx/cdb5059130eadca/lib/python3.12/site-packages/urwid/widget/treetools.pyr   r   0   s    r   r   c                       e Zd ZdZdZ edd      Z edd      Zd fdZddZ	ddZ
dd	Zdd
ZddZddZddZddZddZddZ	 	 	 	 	 	 d fdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddZddZ xZS ) r   z9A widget representing something in a nested tree display.   +r   -c                    || _         d | _        t        |d       | _        d| _        | j                         }t        |   |       y )Nget_first_childT)_node_innerwidgethasattris_leafexpandedget_indented_widgetsuper__init__)selfnodewidget	__class__s      r   r)   zTreeWidget.__init__;   sF    
)-"4):;;))+ r   c                    | j                    S )zS
        Allow selection of non-leaf nodes so children may be (un)expanded
        )r%   r*   s    r   
selectablezTreeWidget.selectableC   s     <<r   c                    | j                         }| j                  s4t        d| j                  | j                  g| j
                     f|gd      }| j                         }t        |t        j                  df|      S )Nr   )dividecharsd   )widthleft)
get_inner_widgetr%   r   unexpanded_iconexpanded_iconr&   get_indent_colsr	   r   RELATIVE)r*   r,   indent_colss      r   r'   zTreeWidget.get_indented_widgetI   sv    &&(||d**D,>,>?NOQWXF **,vj&9&93%?kRRr   c                    | j                   | j                  g| j                     }|t        j                  ddff| j
                  j                  j                  d<   y)z-Update display widget text for parent widgetsr   Fr   N)r7   r8   r&   r   GIVEN_wbase_widgetcontents)r*   icons     r   update_expanded_iconzTreeWidget.update_expanded_iconS   sO     $$d&8&89$--H+/*2B2BAu1M*N$$Q'r   c                X    | j                   | j                         j                         z  S N)r;   get_node	get_depthr/   s    r   r9   zTreeWidget.get_indent_colsY   s"    $--/";";"===r   c                \    | j                   | j                         | _         | j                   S rD   )r#   load_inner_widgetr/   s    r   r6   zTreeWidget.get_inner_widget\   s+    $ $ 6 6 8D   r   c                4    t        | j                               S rD   )r
   get_display_textr/   s    r   rH   zTreeWidget.load_inner_widgeta   s    D))+,,r   c                    | j                   S rD   )r"   r/   s    r   rE   zTreeWidget.get_noded   s    zzr   c                    | j                         j                          d| j                         j                         S )Nz: )rE   get_key	get_valuer/   s    r   rJ   zTreeWidget.get_display_textg   s3    --/))+,Bt}}/H/H/J.MNNr   c                T   | j                         x}|S | j                         }|j                         }|j                         }|P|dkD  rK|j	                         }|j                         }|dz  }||j                         k7  rt        |      ||dkD  rK|y|j                         S )z5Return the next TreeWidget depth first from this one.Nr   r   )first_childrE   next_siblingrF   
get_parent
ValueError
get_widget)r*   rP   	this_node	next_nodedepths        r   next_inorderzTreeWidget.next_inorderj   s      ++--K: MMO	**,	##%EAI!,,.I!..0IQJE	++-- '' EAI ##%%r   c                    | j                   }|j                         x}&|j                         }|j                         x}|S |S |j	                         dk(  ry|j                         j                         S )z9Return the previous TreeWidget depth first from this one.Nr   )r"   prev_siblingrT   
last_childrF   rR   )r*   rU   	prev_nodeprev_widgetr[   s        r   prev_inorderzTreeWidget.prev_inorder   s}    JJ	"//11I> $..0K)4466
C!!  A%##%0022r   c                    | j                   r|S |dv rd| _        | j                          y|dk(  rd| _        | j                          y| j                  j	                         rt
        |   ||      S |S )z2Handle expand & collapse requests (non-leaf nodes)>   rightr   TNr   F)r%   r&   rB   r>   r0   r(   keypressr*   sizekeyr-   s      r   ra   zTreeWidget.keypress   ss     <<J.  DM%%'#:!DM%%'777#D#..
r   c                    | j                   s
|dk7  s|dk7  ry|dk(  r6|| j                         k(  r#| j                   | _        | j                          yy)Nzmouse pressr   Fr   T)r%   r9   r&   rB   )r*   rc   eventbuttoncolrowfocuss          r   mouse_eventzTreeWidget.mouse_event   sR     <<5M1Vq[!8t3355 $-DM%%'r   c                    | j                   s| j                  sy| j                  j                         r*| j                  j	                         }|j                         S y)zReturn first child if expanded.N)r%   r&   r"   has_childrenr!   rT   )r*   
first_nodes     r   rP   zTreeWidget.first_child   sF    <<t}}::""$335J((**r   c                    | j                   s| j                  sy| j                  j                         r)| j                  j	                         j                         }ny|j                         x}|S |S )zReturn last child if expanded.N)r%   r&   r"   rm   get_last_childrT   r[   )r*   r[   last_descendants      r   r[   zTreeWidget.last_child   s`    <<t}}::""$224??AJ)4466OC""r   )r+   r   returnNonerr   bool)rr   zPadding[Text | Columns]rr   rs   rr   int)rr   r
   rr   r   )rr   z=str | tuple[Hashable, str] | list[str | tuple[Hashable, str]])rr   zTreeWidget | None)rc   tuple[int] | tuple[()]rd   strrr   
str | None)rc   rz   rf   r{   rg   rx   rh   rx   ri   rx   rj   ru   rr   ru   )r   r   r   __doc__r;   r   r7   r8   r)   r0   r'   rB   r9   r6   rH   rE   rJ   rX   r^   ra   rk   rP   r[   __classcell__r-   s   @r   r   r   4   s    CK$S!,O"3*M! SO>!
-O&03&$  
	,$  	
    
&	r   r   c                      e Zd ZdZ	 	 	 d	 	 	 	 	 	 	 	 	 ddZdddZddZddZddZddZ	dd	Z
dd
ZddZd Zd ZddZddZddZddZy)r   a:  
    Store tree contents and cache TreeWidget objects.
    A TreeNode consists of the following elements:
    *  key: accessor token for parent nodes
    *  value: subclass-specific data
    *  parent: a TreeNode which contains a pointer back to this object
    *  widget: The widget used to render the object
    Nc                J    || _         || _        || _        || _        d | _        y rD   )_key_parent_value_depth_widget)r*   valueparentrd   rW   s        r   r)   zTreeNode.__init__   s'     	*.r   c                `    | j                   |r| j                         | _         | j                   S )z Return the widget for this node.)r   load_widgetr*   reloads     r   rT   zTreeNode.get_widget   s(    <<6++-DL||r   c                    t        |       S rD   )r   r/   s    r   r   zTreeNode.load_widget   s    $r   c                    | j                   | j                  cxu rn nd| _         | j                   S | j                   "| j                  j                         dz   | _         | j                   S )Nr   r   )r   r   rF   r/   s    r   rF   zTreeNode.get_depth   sT    ;;$,,.DK {{ [[ ,,002Q6DK{{r   c                    | j                         dk(  ry | j                         j                  | j                               S Nr   )rF   rR   get_child_indexrM   r/   s    r   	get_indexzTreeNode.get_index   s2    >>q  00@@r   c                    | j                   S rD   r   r/   s    r   rM   zTreeNode.get_key  s    yyr   c                    || _         y rD   r   r*   rd   s     r   set_keyzTreeNode.set_key	  s	    	r   c                X    | j                         j                  | j                  |       y rD   )rR   change_child_keyr   r   s     r   
change_keyzTreeNode.change_key  s    **499c:r   c                    | j                   (| j                         dkD  r| j                         | _         | j                   S r   )r   rF   load_parentr/   s    r   rR   zTreeNode.get_parent  s4    <<DNN$4q$8++-DL||r   c                    t        d      )zProvide TreeNode with a parent for the current node.  This function
        is only required if the tree was instantiated from a child node
        (virtual function)(virtual function.  Implement in subclassr   r/   s    r   r   zTreeNode.load_parent  s     HIIr   c                    | j                   S rD   )r   r/   s    r   rN   zTreeNode.get_value  s    {{r   c                (    | j                         dk(  S r   )rF   r/   s    r   is_rootzTreeNode.is_root  s    ~~1$$r   c                    | j                         dkD  r-| j                         j                  | j                               S y r   )rF   rR   
next_childrM   r/   s    r   rQ   zTreeNode.next_sibling   2    >>a??$//??r   c                    | j                         dkD  r-| j                         j                  | j                               S y r   )rF   rR   
prev_childrM   r/   s    r   rZ   zTreeNode.prev_sibling&  r   r   c                l    | }|j                         !|j                         }|j                         !|S rD   )rR   )r*   roots     r   get_rootzTreeNode.get_root,  s4    oo+??$D oo+r   NNN)
r   
typing.Anyr   ParentNode | Nonerd   Hashable | NonerW   
int | Nonerr   rs   F)r   ru   rr   r   rr   r   rw   )rr   r   )rr   r   )rd   r   rr   rs   )rr   r   rt   )rr   TreeNode | None)r   r   r   r}   r)   rT   r   rF   r   rM   r   r   rR   r   rN   r   rQ   rZ   r   r   r   r   r   r      s     %)# // "/ 	/
 / 
/ A;
J%r   r   c                       e Zd ZdZ	 	 	 d	 	 	 	 	 	 	 	 	 d fdZdddZddZddZdddZddZ	ddZ
dd	Zdd
ZddZddZddZddZddZ xZS )r   z"Maintain sort order for TreeNodes.c                H    t         |   ||||       d | _        i | _        y )N)r   rd   rW   )r(   r)   _child_keys	_children)r*   r   r   rd   rW   r-   s        r   r)   zParentNode.__init__6  s*     	v3eD6:35r   c                `    | j                   |r| j                         | _         | j                   S )z,Return a possibly ordered list of child keys)r   load_child_keysr   s     r   get_child_keyszParentNode.get_child_keysB  s-    #v#335Dr   c                    t        d      )zHProvide ParentNode with an ordered list of child keys (virtual function)r   r   r/   s    r   r   zParentNode.load_child_keysH      HIIr   c                @    | j                  |      j                         S )z8Return the widget for a given key.  Create if necessary.)get_child_noderT   r   s     r   get_child_widgetzParentNode.get_child_widgetL  s     ""3'2244r   c                |    || j                   vs|r| j                  |      | j                   |<   | j                   |   S )z;Return the child node for a given key. Create if necessary.)r   load_child_node)r*   rd   r   s      r   r   zParentNode.get_child_nodeQ  s8    dnn$"&"6"6s";DNN3~~c""r   c                    t        d      )z6Load the child node for a given key (virtual function)r   r   r   s     r   r   zParentNode.load_child_nodeW  r   r   c                "    || j                   |<   y)zfSet the child node for a given key.

        Useful for bottom-up, lazy population of a tree.
        N)r   )r*   rd   r+   s      r   set_child_nodezParentNode.set_child_node[  s    
 #sr   c                    || j                   v rt        | d      | j                   j                  |      | j                   |<   | j                   |   j                  |       y )Nz is already in use)r   r   popr   )r*   oldkeynewkeys      r   r   zParentNode.change_child_keyb  sU    T^^#!VH,>"?@@!%!3!3F!;vv&&v.r   c           
         	 | j                         j                  |      S # t        $ rO}t        d| d| j	                          d| j                               j                  |j                        |d }~ww xY w)NzCan't find key z in ParentNode z
ParentNode items: )r   indexrS   r   rM   with_traceback__traceback__)r*   rd   excs      r   r   zParentNode.get_child_indexh  sy    	9&&(..s33 	9!!#odlln5EEYZ^ZmZmZoYrsnS../S9	9s   ! 	A9A
A44A9c                    | j                  |      x}8|dz   t        | j                         x}      k  r| j                  ||dz            S y)z=Return the next child node in index order from the given key.Nr   )r   lenr   r   )r*   rd   r   
child_keyss       r   r   zParentNode.next_childp  sW    ))#..E;c`d`s`s`uRuR\Nv@v&&z%!)'<== r   c                ~    | j                  |      x}*|dk\  r%| j                  | j                         |dz
           S y)zAReturn the previous child node in index order from the given key.Nr   )r   r   r   )r*   rd   r   s      r   r   zParentNode.prev_childy  sD    ))#..E;
&&t':':'<UQY'GHHr   c                J    | j                         }| j                  |d         S )z+Return the first TreeNode in the directory.r   r   r   r*   r   s     r   r!   zParentNode.get_first_child  s%    ((*
"":a=11r   c                J    | j                         }| j                  |d         S )z*Return the last TreeNode in the directory.r   r   s     r   rp   zParentNode.get_last_child  s%    ((*
"":b>22r   c                :    t        | j                               dkD  S )z!Does this node have any children?r   )r   r   r/   s    r   rm   zParentNode.has_children  s    4&&()A--r   r   )
r   r   r   r   rd   r   rW   r   rr   rs   r   )r   ru   rr   Sequence[Hashable])rr   r   r   )r   ru   rr   r   )rd   r   rr   r   )rd   r   r+   r   rr   rs   )r   r   r   r   rr   rs   )rd   r   rr   rx   )rd   r   rr   r   ry   rt   )r   r   r   r}   r)   r   r   r   r   r   r   r   r   r   r   r!   rp   rm   r~   r   s   @r   r   r   3  s    ,
 %) 
6
6 "
6 	
6
 
6 

6 J5
#J#/92
3
.r   r   c                  6    e Zd ZdZddZd ZddZd	dZd	dZy)
r   zTListWalker-compatible class for displaying TreeWidgets

    positions are TreeNodes.c                    || _         y)z,start_from: TreeNode with the initial focus.N)rj   )r*   
start_froms     r   r)   zTreeWalker.__init__  s	    
r   c                R    | j                   j                         }|| j                   fS rD   )rj   rT   )r*   r,   s     r   	get_focuszTreeWalker.get_focus  s#    &&(tzz!!r   c                2    || _         | j                          y rD   )rj   	_modified)r*   rj   s     r   	set_focuszTreeWalker.set_focus  s    
r   c                h    |j                         j                         x}||j                         fS yN)NN)rT   rX   rE   r*   r   targets      r   get_nextzTreeWalker.get_next  4     ++-::<<FI6??,,,r   c                h    |j                         j                         x}||j                         fS yr   )rT   r^   rE   r   s      r   get_prevzTreeWalker.get_prev  r   r   Nrv   )rr   z/tuple[TreeWidget, TreeNode] | tuple[None, None])	r   r   r   r}   r)   r   r   r   r   r   r   r   r   r     s       "
r   r   c                  h     e Zd ZdZ	 	 	 	 	 	 d
 fdZddZddZddZddZddZ	ddZ
dd	Z xZS )r   zPA ListBox with special handling for navigation and
    collapsing of TreeWidgetsc                H    t         |   ||      }| j                  ||      S rD   )r(   ra   unhandled_inputrb   s      r   ra   zTreeListBox.keypress  s)    
  '*45##D#..r   c                b    |dk(  r| j                  |       y|dk(  r| j                  |       y|S )zHandle macro-navigation keysr5   Nr   )move_focus_to_parentcollapse_focus_parent)r*   rc   datas      r   r   zTreeListBox.unhandled_input  s7    6>%%d+3;&&t,r   c                    | j                   j                         \  }}| j                  |       | j                   j                         \  }}||k7  r| j                  |d       yy)zCollapse parent directory.r   N)bodyr   r   ra   )r*   rc   r   pos_pwidgetpposs         r   r   z!TreeListBox.collapse_focus_parent  sX     yy**,!!$',,.$$;MM$$ r   c                <   | j                   j                         \  }}|j                         }|y| j                  |      \  }}}|\  }}	}
}}|\  }}|D ]%  \  }}}||z  }||k(  s| j	                  |||        y | j	                  ||j                                y)z(Move focus to parent of widget in focus.N)r   r   rR   calculate_visiblechange_focus)r*   rc   r   r   	parentposmiddletop_bottom
row_offset_focus_widget
_focus_pos_focus_rows_cursor	_trim_top
fill_aboverowss                   r   r   z TreeListBox.move_focus_to_parent  s     yy**,NN$	#55d;WFLC
M:{G #	:", 	GS$$Ji!!$Z8		 	$ 01r   c                &    | j                  |       y rD   )
focus_homer*   rc   s     r   _keypress_max_leftzTreeListBox._keypress_max_left  s    r   c                &    | j                  |       y rD   )	focus_endr  s     r   _keypress_max_rightzTreeListBox._keypress_max_right  s    tr   c                    | j                   j                         \  }}|j                         }| j                  ||       y)zMove focus to very top.N)r   r   r   r   )r*   rc   r   r   rootnodes        r   r  zTreeListBox.focus_home  s5     yy**,<<>$)r   c                    |\  }}| j                   j                         \  }}|j                         j                         j	                         x}r'|j                         }| j                  |||dz
         yy)zMove focus to far bottom.r   N)r   r   r   rT   r[   rE   r   )r*   rc   maxrow_maxcolr   r   
lastwidgetlastnodes           r   r  zTreeListBox.focus_end  sp     yy**,224??AA:A!**,HdHfqj9 Br   )rc   tuple[int, int]rd   r{   rr   r|   )rc   r  r   r{   rr   r|   )rc   r  rr   rs   )r   r   r   r}   ra   r   r   r   r  r	  r  r  r~   r   s   @r   r   r     sL    !// / 
	/	%2.*	:r   r   ) r}   
__future__r   typingcolumnsr   	constantsr   listboxr   r   paddingr	   textr
   r,   r   wimpr   TYPE_CHECKINGcollections.abcr   r   __all__RuntimeErrorr   Unionr   r   r   r   r   r   r   r   <module>r     s   , #   ! (     	2
b	l 	bGFLLw$?@A bJW WtZ. Z.z BN:' N:r   