
    g
f8Q                         d Z dZdZdZdZdZddlZ ej                  dd	       dd
lm	Z	 ddl
mZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ  G d d      Zy)zDHeuristic means to infer the functional/displayed label of a widget.z$Id$z
$Revision$z$Date$z$Copyright (C) 2011-2013 Igalia, S.L.LGPL    NAtspiz2.0)r      )debug)AXComponent)AXHypertext)AXObject)AXTable)AXText)AXUtilitiesc                       e Zd Zd ZddZd Zd Zd Zd Zd Z	d Z
d	 Zd
 ZddZd ZddZddZddZddZddZd Zd Zd Zd Zd ZddZy) LabelInferencec                 <    || _         i | _        i | _        i | _        y)zCreates an instance of the LabelInference class.

        Arguments:
        - script: the script with which this instance is associated.
        N)_script
_lineCache_extentsCache_isWidgetCache)selfscripts     6/usr/lib/python3/dist-packages/orca/label_inference.py__init__zLabelInference.__init__,   s"          c                    d|g}t        j                  t         j                  |d       |sdg fS |rCt        j                  |      s.d|dg}t        j                  t         j                  |d       dg fS dg }}|s=| j                  |      \  }}t        j                  t         j                  d| dd       |r| j                  |      rA| j                  |      xs |\  }}t        j                  t         j                  d| dd       |s=| j                  |      \  }}t        j                  t         j                  d	| dd       |s=| j                  |      \  }}t        j                  t         j                  d
| dd       |s=| j                  |      \  }}t        j                  t         j                  d| dd       |s@t        j                  |      g }}t        j                  t         j                  d| dd       |r"|j                         }|j                  dd      }|s?| j                  |d      \  }}t        j                  t         j                  d| dd       | j!                          ||fS )zAttempt to infer the functional/displayed label of obj.

        Arguments
        - obj: the unlabeled widget
        - focusedOnly: If True, only infer if the widget has focus.

        Returns the text which we think is the label, or None.
        z LABEL INFERENCE: Infer label forTNzLABEL INFERENCE:zis not focusedzLABEL INFERENCE: Text Left: ''zLABEL INFERENCE: Text Right: 'zLABEL INFERENCE: Table: 'zLABEL INFERENCE: Text Above: 'zLABEL INFERENCE: Text Below: 'zLABEL INFERENCE: Name: '
    )	proximityz3LABEL INFERENCE: Text Left with proximity of 200: ')r   printTokens
LEVEL_INFOr   
is_focusedinferFromTextLeftprintMessage_preferRightinferFromTextRightinferFromTableinferFromTextAboveinferFromTextBelowr	   get_namestripreplace
clearCache)r   objfocusedOnlytokensresultobjectss         r   inferzLabelInference.infer8   sp    5c:%**FD98O{55c:(#/?@Fe..=8O"44S9OFGu//3PQWPXXY1Z\`a**3/"55c:DfOFGu//3QRXQYYZ1[]ab"11#6OFGu//3LVHTU1VX\]"55c:OFGu//3QRXQYYZ1[]ab"55c:OFGu//3QRXQYYZ1[]ab &//4bGFu//3KF8ST1UW[\\\^F^^D#.F "44SC4HOFG  EfXQOQUW 	wr   c                 .    i | _         i | _        i | _        y)z5Dumps whatever we've stored for performance purposes.N)r   r   r   )r   s    r   r,   zLabelInference.clearCaches   s      r   c                 Z    t        j                  |      xs t        j                  |      S )zeReturns True if we should prefer text on the right, rather than the
        left, for the object obj.)r   is_check_boxis_radio_buttonr   r-   s     r   r$   zLabelInference._preferRightz   s%     '',P0K0KC0PPr   c                 Z    t        j                  |      xs t        j                  |      S )zeReturns True if we should not permit inference based on text to
        the right for the object obj.r   is_combo_boxis_list_boxr7   s     r   _preventRightzLabelInference._preventRight   %     '',L0G0G0LLr   c                 Z    t        j                  |      xs t        j                  |      S )zZReturns True if we should prefer text above, rather than below for
        the object obj.r9   r7   s     r   
_preferTopzLabelInference._preferTop   r=   r   c                 .    t        j                  |       S )zZReturns True if we should not permit inference based on text below
        the object obj.)r   is_text_inputr7   s     r   _preventBelowzLabelInference._preventBelow   s     ,,S111r   c                     |y fd}t        j                  ||      D cg c]  }| }}t        |      dkD  ryt        j                  |      j                         }|j                   j                  j                        dkD  ryyc c}w )zReturns True if the given object has 'simple' contents, such as text
        without embedded objects or a single embedded object without text.Fc                     | d uxr> j                   j                  j                  |        xr t        j                  |        S )N)r   	utilitiesisStaticTextLeafr   is_link)xr   s    r   isMatchz/LabelInference._isSimpleObject.<locals>.isMatch   sE    D= 1,,00AA!DD1%--a001r   r   T)	r	   iter_childrenlenr   get_all_textr*   countr   EMBEDDED_OBJECT_CHARACTER)r   r-   rI   childchildrenstrings   `     r   _isSimpleObjectzLabelInference._isSimpleObject   s     ;	1
 (0'='=c7'KLeELLx=1$$S)//1<<>>?!C Ms   	B	c                     |yt        j                  |      st        j                  |      ry| j                  |      S )zBReturns True if the given object should not be treated as a label.T)r   
is_headingis_list_item	_isWidgetr7   s     r   _cannotLabelzLabelInference._cannotLabel   s9     ;!!#&+*B*B3*G~~c""r   c                    |y| j                   j                  t        |            }||S t        j                  j
                  t        j                  j                  t        j                  j                  t        j                  j                  t        j                  j                  t        j                  j                  t        j                  j                  t        j                  j                  t        j                  j                  t        j                  j                  t        j                  j                  g}t!        j"                  |      |v }|st%        j&                  |      rd}|| j                   t        |      <   |S )z-Returns True if the given object is a widget.FT)r   gethashr   Role	CHECK_BOXRADIO_BUTTONTOGGLE_BUTTON	COMBO_BOXLISTLIST_BOXMENU	MENU_ITEMENTRYPASSWORD_TEXTPUSH_BUTTONr	   get_roler   is_editable)r   r-   rvwidgetRolesisWidgets        r   rV   zLabelInference._isWidget   s    ;  $$T#Y/>Izz++zz..zz//zz++zzzz**zzzz++zz''zz//zz--
/ $$S)[8K33C8H)1DI&r   c                 H   |sy| j                   j                  t        |      ||f      }|r|S d}t        j                  |      rtt        j                  |      s_|dk(  rt        j                  |      }t        j                  |||      }|j                  |j                  |j                  |j                  f}|d   r|d   sCt        j                  |      }|j                  |j                  |j                  |j                  f}|| j                   t        |      ||f<   |S )zReturns (x, y, width, height) of the text at the given offsets
        if the object implements accessible text, or just the extents of
        the object if it doesn't implement accessible text.)r   r   r   r         )r   rY   rZ   r	   supports_textr   rA   r   get_character_countget_range_rectrH   ywidthheightr   get_rect)r   r-   startOffset	endOffsetri   extentsrectexts           r   _getExtentszLabelInference._getExtents   s    
 ##T#YY$GHI!!#&,,S1? & : :3 ?I,,S+yI&&$&&$**dkkA
wqz&&s+CeeSUUCIIszz9GBIDI{I>?r   c                 l   | j                  |      sdg fS | j                  |      rdg fS | j                  j                  j	                  |d      }|D cg c]  }|d   	 }}t        t        | j                  |            rdg fS |D cg c]  }|d   	 }}dj                  |      |fS c c}w c c}w )z>Gets the functional label text associated with the object obj.NF)useCacher   ro    )	rR   rW   r   rE   getObjectContentsAtOffsetlistfilterrV   join)r   r-   contentscontentr1   stringss         r   _createLabelFromContentsz'LabelInference._createLabelFromContents   s     ##C(8OS!8O<<))CCCRWCX-56'71:66t~~w/08O-56'71:66www(( 7 7s   B,B1c                 P   | j                   j                  t        |            }|r|S t        |      }| j                  |      r*t	        j
                  |      }t        j                  |      }| j                  j                  j                  ||dd      }|| j                   |<   |S )zeGet the (obj, startOffset, endOffset, string) tuples for the line
        containing the object, obj.TF)r   rY   rZ   rV   r   get_link_start_offsetr	   
get_parentr   rE   getLineContentsAtOffset)r   r-   startri   keys        r   _getLineContentszLabelInference._getLineContents   s     __  c+I3i>>#55c:E%%c*C\\##;;CeT!	r   c                    | j                  |      }| j                  |      }|D cg c]  }|d   |k(  s| }}	 |j                  |d         }|d| }d}	t        t	        |      dz
  dd      D ]@  }
||
   \  }}}}| j                  |      }|d   |d   kD  s| j                  |      s;|
dz   }	 n ||	d }|r|d   sdg fS |d   \  }}	}}| j                  ||	|      }|d   |d   |d   z   z
  }d|cxk  r|k  rNn dg fS |D cg c]  }|d   	 }}dj                  |      j                         }|r||D cg c]  }|d   	 c}fS dg fS c c}w # t        $ r t	        |      }Y w xY wc c}w c c}w )aL  Attempt to infer the functional/displayed label of obj by
        looking at the contents of the current line, which are to the
        left of this object

        Arguments
        - obj: the unlabeled widget
        - proximity: pixels expected for a match

        Returns the text which we think is the label, or None.
        r   r   rm   Nrn   ro   r   )	r|   r   index
IndexErrorrK   rangerW   r   r*   )r   r-   r   ry   r   or   r   onLeftr   ilObjlStartlEndlStringlExtentsendrQ   distancer   r0   s                        r   r"   z LabelInference.inferFromTextLeft  s    ""3'((-&6!A$#+166	"NN71:.E !E"s6{QB/ 	A*0)'D&$''-H{WQZ'4+<+<T+BA	 6!98O#)": eS&##D%51:!x{!:;%I% Rx 288gwqz8G8WWW%++-F&Aw
AAARx9 7  	"ME	"( 9  Bs'   EEE E.:E3E+*E+c                 4   | j                  |      rdg fS | j                  |      }| j                  |      }|D cg c]  }|d   |k(  s| }}	 |j                  |d         }|t        t        |      |dz         d }t        |      }	t        |      D ]7  \  }
}| j                  |d         s| j                  |      sdg fc S |
dz   }	 n |d|	 }|r|d   sdg fS |d   \  }}}	}| j                  |||	      }|d   |d   |d   z   z
  }||k  s| j                  |      rH|D cg c]  }|d   	 }}dj                  |      j                         }|r||D cg c]  }|d   	 c}fS dg fS c c}w # t        $ r t        |      }Y 'w xY wc c}w c c}w )aM  Attempt to infer the functional/displayed label of obj by
        looking at the contents of the current line, which are to the
        right of this object

        Arguments
        - obj: the unlabeled widget
        - proximity: pixels expected for a match

        Returns the text which we think is the label, or None.
        Nr   r   rn   ro   r   )r<   r|   r   r   r   rK   min	enumeraterW   r$   r   r*   )r   r-   r   ry   r   r   r   r   onRightr   r   itemrObjr   rQ   rExtentsr   r   r0   s                      r   r%   z!LabelInference.inferFromTextRight:  s    c"8O""3'((-&6!A$#+166	"NN71:.E 3s8}eAg678'l ) 	GAt  a)((-8O!e	 !C.GAJ8O#*1: eS&##D%5A;'!*wqz"9:y D$5$5c$:189gwqz9G9WWW%++-F'Bw
BBBRx9 7  	"ME	"( :  Cs)   E0
E0E5 (FF5FFc                    | j                  |      }|D cg c]  }|d   |k(  s| }}	 |j                  |d         }|dkD  rdg fS | j                  j                  j                  |d   d   |d   d   d      \  }}| j                  ||      }	t        |	      dk7  rdg fS |	d   \  }}
}}| j                  |      rdg fS |j                         r_| j                  ||
|      \  }}}}| j                  |      \  }}}}|||z   z
  }d|cxk  r|k  rn dg fS ||k  r|j                         |gfS dg fS c c}w # t        $ r dg fcY S w xY w)H  Attempt to infer the functional/displayed label of obj by
        looking at the contents of the line above the line containing
        the object obj.

        Arguments
        - obj: the unlabeled widget
        - proximity: pixels expected for a match

        Returns the text which we think is the label, or None.
        r   Nr   T)
r   r   r   r   rE   previousContextrK   rW   r*   r|   )r   r-   r   thisLiner   r   r   prevObj
prevOffsetprevLiner   r   rQ   rH   rs   rt   ru   objXobjYobjWidth	objHeightr   s                         r   r'   z!LabelInference.inferFromTextAbovei  s    ((-&6!A$#+166	NN71:.E 198O"ll44DDQKNHQKND2((*=x=A8O&.qk#VW%8O<<>"&"2"27E3"GAq%.2.>.>s.C+D$)q6z*HH)	) Rx /04i||~y00Rx3 7  	8O	s   D4D4D9 9E	E	c                    | j                  |      rdg fS | j                  |      }|D cg c]  }|d   |k(  s| }}	 |j                  |d         }|dkD  rdg fS | j                  j
                  j                  |d   d   |d   d   dz
  d      \  }}| j                  ||      }	t        |	      dk7  rdg fS |	d   \  }}
}}| j                  |      rdg fS |j                         rZ| j                  ||
|      \  }}}}| j                  |      \  }}}}|||z   z
  }d|cxk  r|k  rn dg fS |j                         |gfS dg fS c c}w # t        $ r dg fcY S w xY w)r   Nr   rm   rn   r   T)rB   r   r   r   r   rE   nextContextrK   rW   r*   r|   )r   r-   r   r   r   r   r   nextObj
nextOffsetnextLiner   r   rQ   rH   rs   rt   ru   r   r   r   r   r   s                         r   r(   z!LabelInference.inferFromTextBelow  s    c"8O((-&6!A$#+166	NN71:.E 198O"ll44@@RLOXb\!_q0$8((*=x=A8O&.qk#VW%8O<<>"&"2"27E3"GAq%.2.>.>s.C+D$)D9,-HH)	) Rx ||~y00Rx3 7  	8O	s   EE E EEc                 V    t        j                  |      ry| j                  |      dk(  S )NTtable)r   is_table_getTagr7   s     r   _isTablezLabelInference._isTable  s'    $||C G++r   c                 V    t        j                  |      ry| j                  |      dk(  S )NTtr)r   is_table_rowr   r7   s     r   _isRowzLabelInference._isRow  s'    ##C(||C D((r   c                 T    t        j                  |      ry| j                  |      dv S )NT)tdth)r   is_table_cellr   r7   s     r   _isCellzLabelInference._isCell  s'    $$S)||C L00r   c                 N    d|cxk  rt        j                  |      k  r||   S  y y )Nr   )r	   get_child_count)r   rowcolindexs      r   _getCellFromRowzLabelInference._getCellFromRow  s.    8833C88x=  9 r   c                 N    t        j                  |      }|j                  d      S )Ntag)r	   get_attributes_dictrY   )r   r-   attrss      r   r   zLabelInference._getTag  s!    ,,S1yyr   c                 	   t        j                  | j                        }| j                  |      sdg fS t        j                        }||t        j                  |      fvrdg fS t        j                  || j
                        }|sdg fS dx}x}x}}	t        j                  || j                        }
t        j                  |d      \  }}|dkD  rit        j                  |||dz
        }t        j                  |||dz         }t        j                  ||dz
  |      }t        j                  ||dz   |      }	n|
rt        j                  |      |
k(  rt        j                  |      }| j                  |
|dz
        }| j                  |
|dz         }t        j                  |
      }t        j                  |
      }|dkD  r+t        j                  ||dz
        }| j                  ||      }|dz   t        j                  |      k  r+t        j                  ||dz         }| j                  ||      }	|r9| j                        s(| j                  |      \  }}|r|j!                         |fS | j#                        \  }}}}|rm| j%                        s\| j#                  |      \  }}}}|||z   z
  }||k  s| j                        r(| j                  |      \  }}|r|j!                         |fS dx}}|r9| j                  |      \  }}|r#| j'                        r|j!                         |fS |	r%| j)                        s| j                  |	      \  }}|rg|re| j#                  |      \  } }!}"}#| j#                  |	      \  }$}%}&}'||!|#z   z
  }(|%||z   z
  })|(|)k  r|j!                         fS |j!                         fS |r|j!                         fS |r|j!                         fS t        j*                  |      }*t-        |*      D +cg c]  }+t        j                  |d|+       },}+|,rt/        t1        | j2                  |,            rdg fS |dk  rdg fS fd}-t        j4                  |      }.t-        d|.      D +cg c]  }+t        j                  ||+|       }/}+t/        t1        |-|/            rdg fS | j                  |,|         \  }}|r|j!                         |fS dg fS c c}+w c c}+w )an  Attempt to infer the functional/displayed label of obj by looking
        at the contents of the surrounding table cells. Note that this approach
        assumes a simple table in which the widget is the sole occupant of its
        cell.

        Arguments
        - obj: the unlabeled widget

        Returns the text which we think is the label, or None.
        NF)prefer_attributerm   r   r   c                     t        j                  |       syt        j                  t        j                  | d             S )NFr   )r	   r   r   have_same_role	get_child)rH   r-   s    r   rI   z.LabelInference.inferFromTable.<locals>.isMatch7  s7    ++A."11(2D2DQ2JCPPPr   )r	   find_ancestorr   rR   r   r   r   r
   get_cell_coordinatesget_cell_atget_index_in_parentr   r   r   r$   r   r*   r|   r<   r?   rB   get_column_countr   r   r   rV   get_row_count)0r   r-   proximityForRightcellparentgridcellLeft	cellRight	cellAbove	cellBelowgridrowrowindexr   	cellindexgridrowParentrowAboverowBelowlabelsourcesr   r   r   r   rH   rs   rt   ru   r   
labelAbove
labelBelowsourcesAbovesourcesBelowaboveXaboveY
aboveWidthaboveHeightbelowXbelowY
belowWidthbelowHeightdAbovedBelowcolumnsr   firstRowrI   rowscellss0    `                                              r   r&   zLabelInference.inferFromTable  s    %%c4<<8##D)8O$$S) 3 3F ;<<8O%%dDMM:8O7;;;9;y9((t{{;$99$QVW(b=**48a<HH++D(HqLII++D(Q,II++D(Q,II,,T2g= 44T:I++GY]CH,,Wi!mDI33G<H$//8M!|#--mX\J 009E	!|h66t<<#--mX\J 009E	D--c2!::8DNE7{{}g--*.*:*:3*?'dHiT//4"&"2"29"=Aq%D8O,H,,0A0A#0F!%!>!>y!Iw ;;='11"&&
Z'+'D'DY'O$Jdooc2!'')<77T//4'+'D'DY'O$J*6:6F6Fy6Q3FFJ6:6F6Fy6Q3FFJVk12Fti/0F!'')<77##%|33##%|33##%|33 **40=B7^LG''a3LL4t~~x @A8Oa<8O	Q
 $$T*AFq$PA$$T1h7PPw&'8O66x7IJw;;='))Rx+ M Qs   S/S4N)T)r   rm   )r   )K   )   )   )2   )__name__
__module____qualname__r   r2   r,   r$   r<   r?   rB   rR   rW   rV   r|   r   r   r"   r%   r'   r(   r   r   r   r   r   r&    r   r   r   r   *   s~    
!9v!QMM2,	#:6)"$*X-^&P)V,)1 mr   r   )__doc____id____version____date____copyright____license__girequire_versiongi.repositoryr   r   r   ax_componentr   ax_hypertextr   	ax_objectr	   ax_tabler
   ax_textr   ax_utilitiesr   r   r   r   r   <module>r     s]   , K6 	   7E "   % %    %[ [r   