grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026a BjŒjýèã@s*ddlmZmZddlmZmZddlmZddlm Z m Z ddl m Z m Z mZmZddlmZmZddlmZddlmZdd lmZmZdd lmZdd lmZmZmZm Z m!Z!m"Z"Gd d „d e#ƒZ$Gdd„deej%e&ƒƒZ'Gdd„dee'ƒZ(Gdd„de'eƒZ)Gdd„de#ƒZ*Gdd„de eƒZ+dS)é)ÚdivisionÚprint_function)ÚxrangeÚwith_metaclass)Úis_mouse_press)Ú SolidCanvasÚ CanvasCombine)ÚWidgetÚnocache_widget_render_instanceÚBOXÚGIVEN)Úcalculate_top_bottom_fillerÚnormalize_valign)Úsignals)Úconnect_signal)Ú MonitoredListÚMonitoredFocusList)ÚWidgetContainerMixin)Ú CURSOR_UPÚ CURSOR_DOWNÚCURSOR_PAGE_UPÚCURSOR_PAGE_DOWNÚCURSOR_MAX_LEFTÚCURSOR_MAX_RIGHTc@s eZdZdS)ÚListWalkerErrorN©Ú__name__Ú __module__Ú __qualname__©rrú3/usr/lib64/python3.9/site-packages/urwid/listbox.pyr#src@s2eZdZdgZdd„Zdd„Zdd„Zdd „Zd S) Ú ListWalkerÚmodifiedcCst |d¡dS)Nr")rZ emit_signal©Úselfrrr Ú _modified)szListWalker._modifiedc Cs4z|j}|||fWStttfy.YdS0dS)zÊ This default implementation relies on a focus attribute and a __getitem__() method defined in a subclass. Override and don't call this method if these are not defined. ©NNN)ÚfocusÚ IndexErrorÚKeyErrorÚ TypeError)r$r'rrr Ú get_focus,s zListWalker.get_focusc Cs6z| |¡}|||fWSttfy0YdS0dS)zÑ This default implementation relies on a next_position() method and a __getitem__() method defined in a subclass. Override and don't call this method if these are not defined. r&N)Ú next_positionr(r)©r$Úpositionrrr Úget_next9s  zListWalker.get_nextc Cs6z| |¡}|||fWSttfy0YdS0dS)zÑ This default implementation relies on a prev_position() method and a __getitem__() method defined in a subclass. Override and don't call this method if these are not defined. r&N)Ú prev_positionr(r)r-rrr Úget_prevFs  zListWalker.get_prevN)rrrrr%r+r/r1rrrr r!&s   r!c@sXeZdZddd„Zdd„ZeeƒZdd„Zdd „Zd d „Z d d „Z dd„Z ddd„Z dS)ÚSimpleListWalkerFcCs6t|ddƒstd|fƒ‚t ||¡d|_||_dS)aœ contents -- list to copy into this object wrap_around -- if true, jumps to beginning/end of list on move This class inherits :class:`MonitoredList` which means it can be treated as a list. Changes made to this object (when it is treated as a list) are detected automatically and will cause ListBox objects using this list walker to be updated. Ú __getitem__Nz4SimpleListWalker expecting list like object, got: %rr)ÚgetattrrrÚ__init__r'Ú wrap_around©r$Úcontentsr6rrr r5Ts  zSimpleListWalker.__init__cCs|S)z_ Return self. Provides compatibility with old SimpleListWalker class. rr#rrr Ú _get_contentsgszSimpleListWalker._get_contentscCs0|jt|ƒkr"tdt|ƒdƒ|_t |¡dS)Nré)r'ÚlenÚmaxr!r%r#rrr r%pszSimpleListWalker._modifiedcCs tdƒ‚dS)z¯ This function inherited from MonitoredList is not implemented in SimpleListWalker. Use connect_signal(list_walker, "modified", ...) instead. ú9Use connect_signal(list_walker, "modified", ...) instead.N©ÚNotImplementedError©r$Úcallbackrrr Úset_modified_callbackusz&SimpleListWalker.set_modified_callbackc CsTz|dks|t|ƒkrt‚Wn$ttfy@td|fƒ‚Yn0||_| ¡dS)úSet focus position.rzNo widget at position %sN)r;Ú ValueErrorr*r(r'r%r-rrr Ú set_focusszSimpleListWalker.set_focuscCs&t|ƒd|kr|jrdSt‚|dS©z3 Return position after start_from. r:r©r;r6r(r-rrr r,‰s zSimpleListWalker.next_positioncCs&|dkr|jrt|ƒdSt‚|dS©z4 Return position before start_from. rr:©r6r;r(r-rrr r0“s  zSimpleListWalker.prev_positioncCs$|rtt|ƒdddƒStt|ƒƒS©zI Optional method for returning an iterable of positions. r:éÿÿÿÿ©rr;©r$Úreverserrr Ú positions�szSimpleListWalker.positionsN)F)F) rrrr5r9Úpropertyr8r%rBrEr,r0rOrrrr r2Ss     r2c@s@eZdZddd„Zdd„Zdd„Zdd „Zd d „Zdd d „ZdS)ÚSimpleFocusListWalkerFcCs0t|ddƒstd|fƒ‚t ||¡||_dS)a8 contents -- list to copy into this object wrap_around -- if true, jumps to beginning/end of list on move This class inherits :class:`MonitoredList` which means it can be treated as a list. Changes made to this object (when it is treated as a list) are detected automatically and will cause ListBox objects using this list walker to be updated. Also, items added or removed before the widget in focus with normal list methods will cause the focus to be updated intelligently. r3Nz9SimpleFocusListWalker expecting list like object, got: %r)r4rrr5r6r7rrr r5§s  ÿ zSimpleFocusListWalker.__init__cCs tdƒ‚dS)z´ This function inherited from MonitoredList is not implemented in SimpleFocusListWalker. Use connect_signal(list_walker, "modified", ...) instead. r=Nr>r@rrr rB¾sz+SimpleFocusListWalker.set_modified_callbackcCs||_| ¡dS)rCN)r'r%r-rrr rEÈszSimpleFocusListWalker.set_focuscCs&t|ƒd|kr|jrdSt‚|dSrFrGr-rrr r,Ís z#SimpleFocusListWalker.next_positioncCs&|dkr|jrt|ƒdSt‚|dSrHrIr-rrr r0×s  z#SimpleFocusListWalker.prev_positioncCs$|rtt|ƒdddƒStt|ƒƒSrJrLrMrrr rOászSimpleFocusListWalker.positionsN)F)F) rrrr5rBrEr,r0rOrrrr rQ¦s     rQc@s eZdZdS)Ú ListBoxErrorNrrrrr rRêsrRc@sheZdZdZdZeegƒZdd„Zdd„Z dd„Z e e e d d �Z dOd d „Z dPdd„Zdd„Zdd„ZdQdd„Zdd„Zdd„Ze edd �Zdd„Ze eedd �Zdd „Zd!d"„Ze d#d$„d%d �Zd&d'„Zd(d)„Zd*d+„Zd,d-„Zd.d/„Zd0d1„ZdRd3d4„Z d5d6„Z!d7d8„Z"d9d:„Z#d;d<„Z$d=d>„Z%d?d@„Z&dAdB„Z'dCdD„Z(dEdF„Z)dGdH„Z*dSdIdJ„Z+dKdL„Z,dMdN„Z-dS)TÚListBoxz0 a horizontally stacked list of widgets TcCs^| |¡zt|jd|jƒWnty:t|ƒ|_Yn0d|_d|_d|_ d|_ d|_ dS)zÌ :param body: a ListWalker subclass such as :class:`SimpleFocusListWalker` that contains widgets to be displayed inside the list box :type body: ListWalker r"r©rr:Úleftúfirst selectableN) Ú _set_bodyrÚ_bodyÚ _invalidateÚ NameErrorr ÚrenderÚ offset_rowsÚinset_fractionÚpref_colÚset_focus_pendingÚset_focus_valign_pending©r$Úbodyrrr r5ôs  zListBox.__init__cCs|jS©N)rXr#rrr Ú _get_bodyszListBox._get_bodycCs*t|ddƒr||_n t|ƒ|_| ¡dS)Nr+)r4rXr2rYrarrr rWs  zListBox._set_bodyz„ a ListWalker subclass such as :class:`SimpleFocusListWalker` that contains widgets to be displayed inside the list box )ÚdocFcCs|\}}|js|jr$| ||f|¡|j ¡\}}|dur>dS|}| ||f¡\}} |rh||krh|d}d} |r’| ¡r’|r’t|dƒr’| |f¡} | durä| \} } | || } | dkr¼| } n(| |krä|| d}|dkrä| d} }| }|  |fd¡}|}|}g}|}|dk�r~|j  |¡\}}|du�r6||8}�q~|}|  |f¡}|�r\|  |||f¡||k�rr||}�q~||8}�q||| |}|dk�rœd}|}|||| }g}|dk�r(|j  |¡\}}|du�rÜ�q(|  |f¡}|�rþ|  |||f¡||k�r||}||8}�q(||8}�q´t d|ƒ}|dk�rz|dk�rz||k�rf||8}||7}d}n||8}||7}d}|}|dk�rô|j  |¡\}}|du�r¦�qô|  |f¡}|  |||f¡||k�rà||}||7}�qô||8}||7}�q~|| |||| f||f||ffS)a Returns the widgets that would be displayed in the ListBox given the current *size* and *focus*. see :meth:`Widget.render` for parameter details :returns: (*middle*, *top*, *bottom*) or (``None``, ``None``, ``None``) *middle* (*row offset*(when +ve) or *inset*(when -ve), *focus widget*, *focus position*, *focus rows*, *cursor coords* or ``None``) *top* (*# lines to trim off top*, list of (*widget*, *position*, *rows*) tuples above focus in order from bottom to top) *bottom* (*# lines to trim off bottom*, list of (*widget*, *position*, *rows*) tuples below focus in order from top to bottom) N)NNNr:Úget_cursor_coordsrT)r_r`Ú_set_focus_completerXr+Úget_focus_offset_insetÚ selectableÚhasattrrfÚrowsr1Úappendr/r<)r$Úsizer'ÚmaxcolÚmaxrowÚ focus_widgetÚ focus_posZtop_posr\Ú inset_rowsÚcursorÚcxÚcyZ effective_cyÚtrim_topÚ focus_rowsÚposZ fill_linesÚ fill_aboveÚprevZp_rowsÚ trim_bottomÚ fill_belowÚnextZn_rowsrrr Úcalculate_visible's° ÿ                       ÿ þzListBox.calculate_visiblecCsJ|\}}|j||f|d�\}}}|dur4td||ƒS|\}} } } } |\} }|\}}g}d}| ¡|D]R\}}}| |f¡}|| ¡kr td|||| ¡fƒ‚||7}| ||df¡qf| j|f|d�}| ¡| krîtd| | | | ¡fƒ‚|j}| du�r| |k�rtd| | | |fƒ‚|| 7}| || d f¡|D]V\}}}| |f¡}|| ¡k�rttd|||| ¡fƒ‚||7}| ||df¡�q8t|ƒ}| �r°|  | ¡|| 8}|�rÈ|  |¡||8}||k�rætd |||ffƒ‚||k�rF| }|�r|d d }|dk�s"|j   |¡d k�r6td|||ffƒ‚|  d||¡|S)zb Render ListBox and return canvas. see :meth:`Widget.render` for details ©r'Nú rzKWidget %r at position %r within listbox calculated %d rows but rendered %d!FzQFocus Widget %r at position %r within listbox calculated %d rows but rendered %d!zhFocus Widget %r at position %r within listbox calculated cursor coords %r but rendered cursor coords %r!TzFListbox contents too long! Probably urwid's fault (please report): %rrKr:r&zGListbox contents too short! Probably urwid's fault (please report): %r)r~rrNr[rkrRrlrsrZtrimZtrim_endrXr/Zpad_trim_top_bottom)r$rmr'rnroÚmiddleÚtopÚbottomÚ_ignorerprqrwrsrvryr{r|Z combinelistrkÚwidgetÚw_posÚw_rowsZcanvasZ focus_canvasZc_cursorZ final_canvasZ bottom_posrrr r[®s`ÿ          zListBox.rendercCsl|\}}| ||fd¡\}}}|dur*dS|\}}} } } | s@dS| \} } | |7} | dks`| |krddS| | fS)zB See :meth:`Widget.get_cursor_coords` for details TNr)r~)r$rmrnror�r‚rƒÚ offset_insetZ_ignore1Z_ignore2Z_ignore3rsÚxÚyrrr rfñsÿ zListBox.get_cursor_coordscCst|tƒ\}}||f|_dS)zøSet the focus widget's display offset and inset. :param valign: one of: 'top', 'middle', 'bottom' ('fixed top', rows) ('fixed bottom', rows) ('relative', percentage 0=top 100=bottom) N)rrRr`)r$ZvalignÚvtÚvarrr Úset_focus_valigns zListBox.set_focus_valignNcCsP|dvrtd|fƒ‚|j ¡\}}|dur4tdƒ‚|||f|_|j |¡dS)aT Set the focus position and try to keep the old focus in view. :param position: a position compatible with :meth:`self._body.set_focus` :param coming_from: set to 'above' or 'below' if you know that old position is above or below the new position. :type coming_from: str )ÚaboveÚbelowNzcoming_from value invalid: %rNz!Can't set focus, ListBox is empty)rRrXr+r(r_rE)r$r.Ú coming_fromrprqrrr rEs ÿ zListBox.set_focuscCs |j ¡S)zå Return a `(focus widget, focus position)` tuple, for backwards compatibility. You may also use the new standard container properties :attr:`focus` and :attr:`focus_position` to read these values. ©rXr+r#rrr r+'szListBox.get_focuscCs|j ¡dS)z^ Return the widget in focus according to our :obj:`list walker `. rr‘r#rrr Ú _get_focus/szListBox._get_focusz7the child widget in focus or None when ListBox is emptycCs"|j ¡\}}|durtdƒ‚|S)z� Return the list walker position of the widget in focus. The type of value returned depends on the :obj:`list walker `. Nz#No focus_position, ListBox is empty)rXr+r()r$Úwrxrrr Ú_get_focus_position7szListBox._get_focus_positiona the position of child widget in focus. The valid values for this position depend on the list walker in use. :exc:`IndexError` will be raised by reading this property when the ListBox is empty or setting this property to an invalid position. csG‡fdd„dtƒ}|ƒS)NcseZdZ”jZdS)z*ListBox._contents..ListBoxContentsN)rrrÚ_contents__getitem__r3rr#rr ÚListBoxContentsIsr–)Úobject)r$r–rr#r Ú _contentsHszListBox._contentsc CsÈt|jddƒ}|rFz||ƒdfWSttfyDtd|fƒ‚Yn0|j ¡\}}z`z*|j |¡|j ¡dWW|j |¡Sttfy¤td|fƒ‚Yn0W|j |¡n|j |¡0dS)Nr3z"ListBox.contents key not found: %rr)r4rXr(r)r+rE)r$ÚkeyÚgetitemr“Z old_focusrrr r•Ls   üzListBox._contents__getitem__cCs|jSrc)r˜r#rrr Ú^ózListBox.a™ An object that allows reading widgets from the ListBox's list walker as a `(widget, options)` tuple. `None` is currently the only value for options. .. warning:: This object may not be used to set or iterate over contents. You must use the list walker stored as :attr:`.body` to perform manipulation and iteration, if supported. cCsdS)z€ There are currently no options for ListBox contents. Return None as a placeholder for future options. Nrr#rrr ÚoptionskszListBox.optionsc Cst|\}}|j\}}d|_d|_|j ¡\}}|dur8dS| |f|¡} t|||t| dddƒ\} } | ||f| ¡dS)zf Finish setting the offset and inset now that we have have a maxcol & maxrow. Nr)r`r_rXr+rkr r Ú shift_focus) r$rmr'rnror‹rŒrprqrkZrtopZrbotrrr Ú_set_focus_valign_completess ÿz"ListBox._set_focus_valign_completecCsÀ|\}}d|_d|_|j||f|d�\}}}|dur8dS|\}} } } } |\} }|\}}|  ¡rbdS|rr|dd…}|| }|D]<\}}}| ¡r²|j |¡| ||f|¡dS||7}q~dS)zr Choose the first visible, selectable widget below the current focus as the focus widget. NrrK)r`r_r~rirXrErž)r$rmr'rnror�r‚rƒÚ row_offsetrprqrwrsrvryr{r|Znew_row_offsetr…rxrkrrr Ú_set_focus_first_selectable‡s0ÿ    ÿz#ListBox._set_focus_first_selectablecCsž|\}}| ¡|jdkr*| ||f|¡S|jdurD| ||f|¡S|j\}}}d|_|j ¡\}} || krpdS|j |¡| ||f|¡\} } } | \} }}}}| \}}| \}}| }|D]4\}}}||8}|| kr¸|  ||f||d¡dSq¸| |}|D]6\}}}|| k�r(|  ||f||d¡dS||7}qú|j | ¡|j ¡\}} |  |f|¡}|dk�rjd}n |dk�r~||}n ||d}|  ||f|¡dS)zO Finish setting the position now that we have maxcol & maxrow. rVNr�rŽré) rYr_r¡r`rŸrXr+rEr~Ú change_focusrkrž)r$rmr'rnror�rprqZnew_focus_widgetr.r�r‚rƒZ focus_offsetrwrsrvryr{r|Úoffsetr…rxrkrrr rg¦sZ ÿ ÿ   ÿ  ÿ      zListBox._set_focus_completecCsŒ|\}}|dkr6||kr(td||fƒ‚||_d|_nJ|j ¡\}}| |fd¡}||dkrntd||fƒ‚d|_| |f|_| ¡dS)a˜ Move the location of the current focus relative to the top. This is used internally by methods that know the widget's *size*. See also :meth:`.set_focus_valign`. :param size: see :meth:`Widget.render` for details :param offset_inset: either the number of rows between the top of the listbox and the start of the focus widget (+ve value) or the number of lines of the focus widget hidden off the top edge of the listbox (-ve value) or ``0`` if the top edge of the focus widget is aligned with the top edge of the listbox. :type offset_inset: int rz2Invalid offset_inset: %r, only %r rows in list boxrTTz1Invalid offset_inset: %r, only %r rows in target!N)rRr\r]rXr+rkrY)r$rmrˆrnroÚtargetr„Útgt_rowsrrr ržás  zListBox.shift_focusc Cs€|\}}|j ¡\}}|dur"dSd}t|dƒr<| |f¡}|durnt|dƒrn| |f¡}t|ƒtkrn|\}}|dur|||_dS)z+Update self.pref_col from the focus widget.NÚ get_pref_colrf)rXr+rjr§rfÚtypeÚtupler^) r$rmrnror…Zold_posr^ZcoordsrŠrrr Úupdate_pref_col_from_focuss     z"ListBox.update_pref_col_from_focusrcCsH|\}}|r|d|_n| ||f¡| ¡|j |¡|j ¡\} } |  |fd¡} |durf|d}d} || } |dkr¶|  ¡r¶|| kr¶||| krœ| }n||| kr®| }n||8}|dkrú|  ¡rú|| krú|| |krà| }n|| |krò| }n||7}|dk�r||_d|_ n0|| dk�r0t d|| fƒ‚d|_| | f|_ |du�rb|du�rZdS|jf}t | d ƒ�srdSg}t |ƒdk�rÀ|\}|dk�r t d| ƒ}n|dk�s²Jd ƒ‚t | d d ƒ}n`|\}}|dk�sÜ|| k�rìt d || fƒ‚|dk�rt |d d ƒ}n|dk�rt || ƒ}n|g}|D]}|  |f||¡�r$�qD�q$dS) aÑ Change the current focus widget. This is used internally by methods that know the widget's *size*. See also :meth:`.set_focus`. :param size: see :meth:`Widget.render` for details :param position: a position compatible with :meth:`self._body.set_focus` :param offset_inset: either the number of rows between the top of the listbox and the start of the focus widget (+ve value) or the number of lines of the focus widget hidden off the top edge of the listbox (-ve value) or 0 if the top edge of the focus widget is aligned with the top edge of the listbox (default if unspecified) :type offset_inset: int :param coming_from: either 'above', 'below' or unspecified `None` :type coming_from: str :param cursor_coords: (x, y) tuple indicating the desired column and row for the cursor, a (x,) tuple indicating only the column for the cursor, or unspecified :type cursor_coords: (int, int) :param snap_rows: the maximum number of extra rows to scroll when trying to "snap" a selectable focus into the view :type snap_rows: int rTNr:rŽr�rTz1Invalid offset_inset: %s, only %s rows in target!Úmove_cursor_to_coordszLmust specify coming_from ('above' or 'below') if cursor row is not specifiedrKzLcursor_coords row outside valid range for target. pref_row:%r target_rows:%r)r^rªrYrXrEr+rkrir\r]rRrjr;Úranger«)r$rmr.rˆr�Z cursor_coordsÚ snap_rowsrnror¥r„r¦Z align_topZ align_bottomZ attempt_rowsr^Úpref_rowÚrowrrr r£s~  ÿþ  ÿþ            zListBox.change_focusc Cs�|\}}|j ¡\}}| |fd¡}|j}d}|dkrˆ|j\} } | dksX| dksX| | krhtd|jfƒ‚|| | }|rˆ||krˆtdƒ‚||fS)z2Return (offset rows, inset rows) for focus widget.TrzInvalid inset_fraction: %rz*urwid inset_fraction error (please report))rXr+rkr\r]rR) r$rmrnrorprxrwr\rrZinumZidenrrr rh†s   zListBox.get_focus_offset_insetc Cs¼|\}}|j ¡\}}|dur"dS| ¡s.dSt|dƒs.actual_key)r_r`rgrXr+riÚkeypressr°Z _command_maprÚ _keypress_uprÚ_keypress_downrÚ_keypress_page_uprÚ_keypress_page_downrÚ_keypress_max_leftrÚ_keypress_max_right)r$rmr™rnrorprxr²rr±r r³²s2   zListBox.keypresscCs"tt|j ¡ƒƒ|_| d¡dS)Nr‚T©r}ÚiterrbrOÚfocus_positionr�©r$rmrrr r¸ås zListBox._keypress_max_leftcCs&tt|jjdd�ƒƒ|_| d¡dS)NT©rNrƒrºr½rrr r¹ês zListBox._keypress_max_rightcCsð|\}}| ||fd¡\}}}|dur*dS|\}}} } } |\} } |}| }d}| D]8\}}}||8}|rP| ¡rP| ||f||d¡dSqP|d7}| ¡|dkrú|j |¡\}}|dur¾dS| |fd¡}||8}|rš| ¡rš| ||f||d¡dSqš| ¡�r|d|k�rH|du�r0| ||f|¡dS| ||f||d¡dS| du�rØ| \}}||d|k�rØ|du�rª|j |¡\}}|du�r”dS| |fd¡}||8}| |k�rÀ|d }| ||f||d¡dS| ||f|d¡dS)NTr�r:r)r~rir£rYrXr1rkrž)r$rmrnror�r‚rƒÚfocus_row_offsetrprqr„rsrvryr rxr…rkr‰rŠrrr r´ïslÿ    ÿ  ÿ  ÿ      ÿzListBox._keypress_upcCsô|\}}| ||fd¡\}}}|dur*dS|\}}} } } |\} } || }| }| }d}| D]8\}}}|rˆ| ¡rˆ| ||f||d¡dS||7}qX|d8}| ¡||k�r|j |¡\}}|durÈdS| |f¡}|rø| ¡rø| ||f||d¡dS||7}q¢| ¡�r|| ddk�r\|du�r@| ||f||¡dS| ||f|||d¡dS| du�rÜ| \}}||ddk�rÜ|du�rª|j |¡\}}|du�r²dSn||8}||k�rÄ|d}| ||f||d¡dS| ||f|d¡dS)NTrŽr:r)r~rir£rYrXr/rkrž)r$rmrnror�r‚rƒr¿rprqrwrsr{r|r rkrxr…r‰rŠrrr rµ<spÿ    ÿ     ÿ   ÿ ÿ     ÿzListBox._keypress_downc% s–|\}}| ||fd¡\}}}|dur*dS|\}}} } } |\} } |}| ¡sR|}n*| durj| \}}| }n|dkrxd}n|}||}||}d}}g}| ||| | f¡| }| D]$\}}}||8}| ||||f¡q²t|ƒ}|| k�rD|j |¡\}}|du�r �qD| |f¡}||8}|dk�r0|d7}| ||||f¡qà|d\}}}}|dk�rv| ‰‡fdd„|Dƒ}|d\}}}}||k�rž|d=|d8}| ||f¡tt |t|ƒƒƒtt |dddƒƒ}g‰d}|D�]4}||\}}}}| ¡�s�qÞ|�s �qÞt d| ƒ}||dk�r^|  ||f||d d|j |df|| |d¡n|  ||f||d|j |f|¡| �rœ|j | dd¡dk�rœ| ||fd¡\}}}|\}} }!}"}#|||k�r܈ |¡�qÞ||k�rôˆ |¡�qÞ|dk�rˆ |¡d}�qÞdS|�r dS| �rJ| ¡�rJ|j | dd¡dk�rJ‡fd d„|Dƒ}$|$|D]r}||\}}}}|| k�r†�qd|�s��qd||dk�rº|| |d8}|d }|  ||f||dd|¡dS|  ||ft|d|ƒ¡| ||fd¡\}}}|\}} }}!}"||k�r$dS|�s.dS|d\} }!}}"|j |¡\}}|du�r\dS| |fd¡}|  ||f||d d|j |dfd¡dS) NTrr:rKcs$g|]\}}}}|ˆ|||f‘qSrr©Ú.0Úror“ÚpÚr©Úadjustrr Ú Ïrœz-ListBox._keypress_page_up..r�r&csg|]}|ˆvr|‘qSrr©rÁÚj©Ú bad_choicesrr rÇrœ)r~rirlr;rXr1rkrªÚlistrr<r£r^ržÚmin)%r$rmrnror�r‚rƒr rprqrwrsrvryZtopmost_visibleÚscroll_from_rowr‰rŠr­Útrxr…rkÚsnap_region_startr“rÃrÄÚ search_orderÚcut_off_selectable_chosenÚir®Úact_row_offsetÚ_ign1Ú_ign2Ú_ign3Ú_ign4Ú good_choicesr©rÆrËr r¶Žsìÿ       ÿ      ý  þÿÿ         þÿ   ÿzListBox._keypress_page_upc$ s^|\}}| ||fd¡\}}}|dur*dS|\}}} } } |\} } ||}| ¡sV|}n,| durp| \}}|d}n|| kr~| }n|}||}| }d}}g}| ||| | f¡| }|| 7}| D]$\}}}| ||||f¡||7}q¾t|ƒ}|||k�rP|j |¡\}}|du�r�qP| |f¡}| ||||f¡||7}||krì|d7}qì|d\}}}}|||k�rŒ|||‰‡fdd„|Dƒ}|d\}}}}||dk�r¸|d=|d8}| ||f¡tt |t|ƒƒƒtt |dddƒƒ}g‰d}|D�]}||\}}}}| ¡�s�qø|�s&�qøt ||d|dƒ}||k�rv|  ||f||dd|j df|||d¡n|  ||f||d|j |f|¡| ||fd¡\}}}|\}}} }!}"|||k�rÔˆ |¡�qø||k�r술|¡�qø|||k�r ˆ |¡d}�qødS|�rdS‡fdd„|Dƒ}#|#|D]n}||\}}}}|| k�rX�q6|�sb�q6||k�rˆ||||d8}|d}|  ||f||dd|¡dS|  ||ftd| |ƒ¡| ||fd¡\}}}|\}}}} }!||k�ròdS|�südS|d\}} }}!|j |¡\}}|du�r*dS| |fd¡}|  ||f||dd|j dfd¡dS) NTr:rKcs$g|]\}}}}|ˆ|||f‘qSrrrÀrÅrr rLjrœz/ListBox._keypress_page_down..rrŽcsg|]}|ˆvr|‘qSrrrÈrÊrr rÇËrœ)r~rirlr;rXr/rkrªrÌrrÍr£r^ržr<)$r$rmrnror�r‚rƒr rprqrwrsr{r|Z bottom_edgerÎr‰rŠr­rÏrxr…rkrÐr“rÃrÑrÒrÓr®rÔrÕrÖr×rØrÙrrÚr r·Gsäÿ       ÿ    ý  þÿ        þÿ    ÿzListBox._keypress_page_downcCsö|\}}|j||fdd�\} } } | dur,dS| \} } }}}| \}}| \} }| ¡|| ||fg|}| }|D]"\}}}|||krŠq˜||7}qpdS|o¢|| k}t|ƒrÎ|dkrÎ| ¡rÎ| ||f||¡t|dƒsÜdS| |f||||||¡S)zf Pass the event to the contained widgets. May change focus on button 1 press. TrNFr:Ú mouse_event)r~rNrrir£rjrÛ)r$rmZeventZbuttonÚcolr¯r'rnror�r‚rƒr„rprqrwrsrvryr|Zw_listZwrowr“r†r‡rrr rÛös< ÿ  ÿþ    ÿzListBox.mouse_eventcCsö|\}}g}|j||f|d�\}}}|dur4ddgS|\} } |\} } | dkr¨|\} }}}}| |7} | D]\}}}| |7} qf| |krŽ| d¡n|j |¡dkr¨| d¡| dkrò|\} }}}}| D]\}}}| |8} qÂ|j |¡dkrò| dd¡|S)a+ Return a list that may contain ``'top'`` and/or ``'bottom'``. i.e. this function will return one of: [], [``'top'``], [``'bottom'``] or [``'top'``, ``'bottom'``]. convenience function for checking whether the top and bottom of the list are visible rNr‚rƒrr&)r~rlrXr/r1Úinsert)r$rmr'rnroÚlr�r‚rƒrvrŽr{r�r r“rxrkÚcrrr Ú ends_visibles2  ÿ      zListBox.ends_visibleccsŠt|jddƒ}|r(|ƒD] }|VqdS|j ¡\}}|durBdS|}|V|j |¡\}}|sFqdqF|}|j |¡\}}|s~q†|VqhdS)a= Return an iterator over the positions in this ListBox. If self._body does not implement positions() then iterate from the focus widget down to the bottom, then from above the focus up to the top. This is the best we can do with a minimal list walker implementation. rON)r4rXr+r/r1©r$Z positions_fnrxrprqr“rrr Ú__iter__Ds  zListBox.__iter__ccsŽt|jddƒ}|r,|dd�D] }|VqdS|j ¡\}}|durFdS|}|j |¡\}}|s`qh|VqJ|}|V|j |¡\}}|slqŠqldS)aª Return a reversed iterator over the positions in this ListBox. If :attr:`body` does not implement :meth:`positions` then iterate from above the focus widget up to the top, then from the focus widget down to the bottom. Note that this is not actually the reverse of what `__iter__()` produces, but this is the best we can do with a minimal list walker implementation. rONTr¾)r4rXr+r1r/rárrr Ú __reversed__as zListBox.__reversed__)F)F)N)rNNN)F).rrrÚ__doc__Z _selectableÚ frozensetr Z_sizingr5rdrWrPrbr~r[rfr�rEr+r’r'r”r¼r˜r•r8r�rŸr¡rgržrªr£rhr°r³r¸r¹r´rµr¶r·rÛràrârãrrrr rSís^ #  C ÿ  ; þ r3MR:0( &rSN),Z __future__rrZ urwid.compatrrZ urwid.utilrZ urwid.canvasrrZ urwid.widgetr r r r Zurwid.decorationr rZurwidrZ urwid.signalsrZurwid.monitored_listrrZurwid.containerrZurwid.command_maprrrrrrÚ ExceptionrZ MetaSignalsr—r!r2rQrRrSrrrr Ús      -SD