
    f\                     N   d dl mZmZmZ d dlZd dlZd dlZ ej                  e      Z	d dl
mZ  e        	 d dlmZ d dlmZmZ d dlmZ d dlmZmZ d dlmZmZ d d	lmZ d d
lmZ d dlm Z   e        Z! G d d      Z" G d de"      Z# G d de"      Z$y# e$ r
ZY dZ[bdZ[ww xY w)    )divisionprint_functionunicode_literalsN)require_gi_versions)Atspi)AtspiStateTrackerAtspiStateType)TextDomains)TextChangesTextSpan)KeyCodeunicode_str)Timer)	KeyCommon)Configc                   \    e Zd ZdZd Zd Zd Zd Zd ZddZ	ddZ
d	 Zd
 Zd Zd Zd Zy)TextContextzO
    Keep track of the current text context and intecept typed key events.
    c                      y N selfs    5/usr/lib/python3/dist-packages/Onboard/TextContext.pycleanupzTextContext.cleanup4           c                      y r   r   r   s    r   resetzTextContext.reset7   r   r   c                     t               S r   NotImplementedErrorr   s    r   can_insert_textzTextContext.can_insert_text:       "$$r   c                     t               S r   r    )r   offsettexts      r   insert_textzTextContext.insert_text=   r#   r   c                     t               S r   r    )r   r&   s     r   insert_text_at_caretz TextContext.insert_text_at_caret@   r#   r   c                     t               S r   r    r   r%   lengths      r   delete_textzTextContext.delete_textC   r#   r   c                     t               S r   r    )r   r,   s     r   delete_text_before_caretz$TextContext.delete_text_before_caretF   r#   r   c                     t               r   r    r   s    r   get_contextzTextContext.get_contextI       !##r   c                     t               r   r    r   s    r   get_linezTextContext.get_lineL   r2   r   c                     t               r   r    r   s    r   get_line_caret_poszTextContext.get_line_caret_posO   r2   r   c                     t               r   r    r   s    r   get_changeszTextContext.get_changesR   r2   r   c                     t               r   r    r   s    r   clear_changeszTextContext.clear_changesU   r2   r   N   )__name__
__module____qualname____doc__r   r   r"   r'   r)   r-   r/   r1   r4   r6   r8   r:   r   r   r   r   r   /   sC    %%%%%$$$$$r   r   c                   "   e Zd ZdZ e       Zd Zd 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 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd.dZd.d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) Z,d* Z-d+ Z.d, Z/y)0AtspiTextContextz<
    Keep track of the current text context with AT-SPI
    c                    || _         d | _        d| _        t               | _        | j                  j                         | _        t               | _        d| _	        d| _
        d| _        d| _        d| _        t               | _        d| _        d | _        d | _        d| _        d| _        d| _        d | _        d | _        t1               | _        d| _        | j4                  | _        y )NF r   g{Gz?)_wp_accessible_can_insert_textr
   _text_domainsget_nop_domain_text_domainr   _changes_entering_text_text_changed_context_line_line_caretr   _selection_span_begin_of_text_begin_of_text_offset_pending_separator_span_last_text_change_time_last_caret_move_time_last_caret_move_position_last_context
_last_liner   _update_context_timer_update_context_delay_normal_update_context_delay)r   wps     r   __init__zAtspiTextContext.__init__`   s     %(] ..==?##"
'z#%)"'+$&'#%&")*&!%*W",0)%)%F%F"r   c                 &    | j                  d       y NF_register_atspi_listenersr   s    r   r   zAtspiTextContext.cleanup   s    &&u-r   c                 &    | j                  |       y r   ra   )r   enables     r   rd   zAtspiTextContext.enable   s    &&v.r   c                     | j                   S r   )rJ   r   s    r   get_text_domainz AtspiTextContext.get_text_domain   s       r   Nc                 0    | j                   |ur|| _         yy)z3 Remember this separator span for later insertion. NrT   )r   separator_spans     r   set_pending_separatorz&AtspiTextContext.set_pending_separator   s    ''~=+9D( >r   c                     | j                   S )z/ Return current pending separator span or None rh   r   s    r   get_pending_separatorz&AtspiTextContext.get_pending_separator   s    +++r   c                     | j                   y| j                  s| j                  r| j                         r| j                  S y)zm
        Returns the predictions context, i.e. some range of
        text before the caret position.
        rD   )rF   rL   rM   can_suggest_before_typingrN   r   s    r   r1   zAtspiTextContext.get_context   s@    
 # !!))+== r   c                     d}| j                   r6| j                         }| j                  r| j                         }|r|dz   |z   }|S )zd
        Returns the predictions context with
        begin of text marker (at text begin).
        rD    )rF   r1   rR   get_text_begin_marker)r   contextmarkers      r   get_bot_contextz AtspiTextContext.get_bot_context   sO    
 &&(G ""335$slW4Gr   c                 x    | j                         }| j                  || j                  j                         z  }|S )zE
        Context including bot marker and pending separator.
        )rt   rT   get_span_text)r   rr   s     r   get_pending_bot_contextz(AtspiTextContext.get_pending_bot_context   s<     &&(''3t33AACCGr   c                 6    | j                   r| j                  S dS NrD   )rF   rO   r   s    r   r4   zAtspiTextContext.get_line   s!    "" zz 	+(*	+r   c                 6    | j                   r| j                  S dS Nr   )rF   rP   r   s    r   r6   z#AtspiTextContext.get_line_caret_pos   s#    ""  	*()	*r   c                 P    | j                   r| j                  | j                  d  S dS ry   )rF   rO   rP   r   s    r   get_line_past_caretz$AtspiTextContext.get_line_past_caret   s/    "" zz$**+, 	+(*	+r   c                 6    | j                   r| j                  S d S r   )rF   rQ   r   s    r   get_selection_spanz#AtspiTextContext.get_selection_span   s#    "" ## 	-(,	-r   c                 b    | j                   sy | j                  j                         }d|_        |S r{   )rF   rQ   copyr,   )r   spans     r   get_span_at_caretz"AtspiTextContext.get_span_at_caret   s.    ##((*r   c                 R    | j                   r| j                  j                         S dS r{   )rF   rQ   beginr   s    r   	get_caretzAtspiTextContext.get_caret   s,     ##))+ 	'%&	'r   c                 B    | j                   }|r|j                  |      S y r   )rF   get_character_extents)r   r%   
accessibles      r   r   z&AtspiTextContext.get_character_extents   s$    %%
33F;;r   c                 H    | j                         }|r|j                         S yry   )rf   rq   r   domains     r   rq   z&AtspiTextContext.get_text_begin_marker   s%    %%'//11r   c                 N    | j                         }|r|j                  |||      S yNT)rf   can_record_insertion)r   r   posr,   r   s        r   r   z%AtspiTextContext.can_record_insertion   s+    %%'..z3GGr   c                 H    | j                         }|r|j                         S yr   )rf   rn   r   s     r   rn   z*AtspiTextContext.can_suggest_before_typing   s%    %%'3355r   c                 ^    | j                         }|r|j                  | j                        S yr`   )rf   can_auto_punctuaterR   r   s     r   r   z#AtspiTextContext.can_auto_punctuate   s-    %%',,T-@-@AAr   c                 6    | j                   r| j                  S d S r   )rF   rS   r   s    r   get_begin_of_text_offsetz)AtspiTextContext.get_begin_of_text_offset   s#    "" )) 	-(,	-r   c                     | j                   S r   )rK   r   s    r   r8   zAtspiTextContext.get_changes   s    }}r   c                 8    | j                   j                          S )z! Are there any changes to learn? )rK   is_emptyr   s    r   has_changeszAtspiTextContext.has_changes   s    ==))+++r   c                 8    | j                   j                          y r   )rK   clearr   s    r   r:   zAtspiTextContext.clear_changes  s    r   c                 H    t        | j                        xr | j                  S )z@
        Can delete or insert text into the accessible?
        )boolrF   rG   r   s    r   r"   z AtspiTextContext.can_insert_text  s     
 D$$%?$*?*??r   c                 B    | j                   j                  |||z          y)< Delete directly, without going through faking key presses. N)rF   r-   r+   s      r   r-   zAtspiTextContext.delete_text  s    $$VVf_=r   c                     	 | j                   j                         }| j                  ||z
  |       y# t        $ r+}t        j	                  dt        |      z          Y d}~yd}~ww xY w)r   z(TextContext.delete_text_before_caret(): N)rF   get_caret_offset	Exception_loggerinfor   r-   )r   r,   caret_offsetexs       r   r/   z)AtspiTextContext.delete_text_before_caret  sb    	++<<>L 	.7  	LLC$R) *	s   2 	A&!A!!A&c                 D   | j                   j                  ||       |}	 | j                   j                         }|r.||k(  r(| j                   j                  |t        |      z          yyy# t        $ r+}t        j                  dt        |      z          Y d}~yd}~ww xY w)zL
        Insert directly, without going through faking key presses.
        zTextContext.insert_text(): N)	rF   r'   r   r   r   r   r   set_caret_offsetlen)r   r%   r&   offset_beforeoffset_afterr   s         r   r'   zAtspiTextContext.insert_text  s     	$$VT2 	++<<>L M\1--mc$i.GH 24  	LL6$R) *	s   A+ +	B4!BBc                     	 | j                   j                         }| j                  ||       y# t        $ r+}t        j	                  dt        |      z          Y d}~yd}~ww xY w)z
        Insert directly, without going through faking key presses.
        Fails for terminal and firefox, unfortunately.
        z$TextContext.insert_text_at_caret(): N)rF   r   r   r   r   r   r'   )r   r&   r   r   s       r   r)   z%AtspiTextContext.insert_text_at_caret0  s]    
	++<<>L 	t,  	LL?$R) *	s   / 	A#!AA#c                 r   | j                   }|rU|j                  d| j                         |j                  d| j                         |j                  d| j                         y |j                  d| j                         |j                  d| j                         |j                  d| j                         y )Nztext-entry-activatedztext-changedztext-caret-moved)_state_trackerconnect_on_text_entry_activated_on_text_changed_on_text_caret_moved
disconnect)r   registersts      r   rb   z*AtspiTextContext._register_atspi_listeners>  s      JJ-t/L/LMJJ~t'<'<=JJ)4+D+DE MM0$2O2OPMM.$*?*?@MM,d.G.GHr   c                 V    d}|r$d|j                         v r|j                         rd}|S )NFEditableTextT)get_interfacesis_toolkit_gtk3)r   r   r"   s      r   get_accessible_capabilitiesz,AtspiTextContext.get_accessible_capabilitiesK  s6     !:!:!<< --/&*Or   c                    | j                   j                          || _        d| _        d| _        |rQ|j                          |j                          |j                          |j                          |j                         }ni } | j                  j                  di || _        | j                  j                          | j                  |      | _        t         j#                  t         j$                        r5t         j&                  } |d        |d       d}|r|j)                         }t+        |j-                               D ]o  \  }}t/        |      dz   }|dk(  r"|t1        t3        j4                  |            z  }n*t7        |d      r||j8                  z  }n|t1        |      z  } |||z          q  ||dj;                  | j                  xr t=        | j                        j>                        z           ||d	j;                  | j                        z          n ||d
z          | jA                          | j                   jC                          y )NFzF----------------------------------------------------------------------zAccessible focused: z    =z	state-set
value_nameztext_domain: {}zcan_insert_text: {}Noner   )"rE   on_text_entry_deactivatedrF   rL   rM   get_roleget_attributesr   	is_urlbar	get_staterH   
find_matchrJ   init_domainr   rG   r   isEnabledForLEVEL_ATSPIatspiget_all_statesorteditemsstrreprr	   
to_stringshasattrr   formattyper=   _update_contexton_text_entry_activated)r   r   statelogindentkeyvaluemsgs           r   r   z)AtspiTextContext._on_text_entry_activated_  s   **, &#" !%%'%%'  "((*EE :D..99BEB%%' ,,Z8 	  3 34--CM&'F"002"("7 &JCc(S.Ck)tN$=$=e$DEE 5u///tE{*%& F.VD-- = !2!23<<>> ? F2VD1123 4 FVO$((*r   c                    | j                  |j                  |j                  |j                        }|r7	 | j                  j                         }| j                  j                  ||       t        j                         | _        | j                          y # t        $ r+}t        j                  dt        |      z          Y d }~Yd }~ww xY w)Nz TextContext._on_text_changed(): )_record_text_changer   r,   insertrF   r   rE   on_text_insertedr   r   r   r   timerU   r   )r   eventinsertion_spanr   r   s        r   r   z!AtspiTextContext._on_text_changed  s    11%))27,,27,,@ H#//@@B
 )).,G&*iik#  -?'O, - --s   B 	C	!CC	c                     t        j                          | _        |j                  | _        | j	                          | j
                  j                          y r   )r   rV   caretrW   r   rE   on_text_caret_movedr   r   s     r   r   z%AtspiTextContext._on_text_caret_moved  s8    %)YY[").&$$&r   c                      y)z< disabled, Francesco didn't receive any AT-SPI key-strokes. Nr   r   s     r   _on_atspi_key_pressedz&AtspiTextContext._on_atspi_key_pressed  s    r   c                     |j                         r`d}|j                         rt        j                  }n*|j	                         }|dk(  s|dk(  rt        j
                  }| j                  ||       y y )Nr   Cc)is_text_changing	is_returnr   KP_Enter	get_labelr   _handle_key_press)r   r   mod_maskkeycodelabels        r   on_onboard_typingz"AtspiTextContext.on_onboard_typing  s]    !G}}!**C<5C<%iiG""7H5 "r   c                     | j                   rl| j                         }|rY|j                  ||      \  | _        }|du r| j                  j                          y |du r| j                  j                          y y y y )NTF)rF   rf   handle_key_pressrL   rE   commit_changesdiscard_changes)r   r   	modifiersr   end_of_editings        r   r   z"AtspiTextContext._handle_key_press  sy    ))+F++GY? 4#^ "T)HH++-#u,HH,,. -  r   c                    | j                   }d }d }|r	 |j                         }|1g }|r| j                  rz| j                  |||      rg| j                  j                         s|dk  rd}nd}t        |dz
  d      }	t        ||z   dz   |      }
	 |j                  |	|
      }t        ||||	      }nd }| j                  j                  |||      }n'| j                  j!                  ||| j                        }|D ][  }t        |j#                         dz
  d      }	t        |j%                         dz   |      }
	 |j                  |	|
      |_        |	|_        ] d	| _        |S #  d }Y DxY w# t        $ r+}t        j                  dt        |      z          Y d }~d }~ww xY w# t        $ r2}t        j                  dt        |      z          d|_        Y d }~d }~ww xY w)
N      d   r   z%TextContext._record_text_change() 1: z%TextContext._record_text_change() 2: rD   T)rF   get_character_countrL   r   rE   	is_typingmaxminget_textr   r   r   r   r   rK   r   deleter   endr&   text_posrM   )r   r   r,   r   r   r   
char_countspans_to_updateinclude_lengthr   r  r&   r   r   s                 r   r   z$AtspiTextContext._record_text_change  s   %%

"';;=

 ! O&&,,ZfExx))+v{ *,
 *+  c	1-EcFlS0*=CL)225#>
 *2#vtU)K &*N"&--"6"6sF7E#G #'--"6"6sF7;7J7J#L ( & DJJL3.2$((*s*J7# * 3 3E3 ?DI
 !&& "u"!
0 % 6%L%0_&5 6 660 ! #LL!H!,R"1 2 "DII#s;   E! E+ 8F"!E(+	F4!FF"	G+(GGc                     || _         y r   )r\   )r   delays     r   set_update_context_delayz)AtspiTextContext.set_update_context_delay  s
    %*"r   c                 &    | j                   | _        y r   )r[   r\   r   s    r   reset_update_context_delayz+AtspiTextContext.reset_update_context_delay  s    %)%F%F"r   c                 d    | j                   j                  | j                  | j                         y r   )rZ   startr\   on_text_context_changedr   s    r   r   z AtspiTextContext._update_context  s(    ""(()C)C)-)E)E	Gr   c                 T   | j                   rT| j                  | j                  z
  dkD  r8| j                  | j                   j	                         k7  r| j                  d        | j                  j                  | j                  | j                        }||\  | _
        | _        | _        | _        | _        | _        | j!                         }| j"                  |k7  xs | j$                  | j                  k7  }|r|| _        | j                  | _        | j                  j'                  |       y)Ng      ?F)rT   rV   rU   rW   r   rj   rJ   read_contextrE   rF   rN   rO   rP   rQ   rR   rS   rw   rX   rY   r  )r   resultrr   change_detecteds       r   r  z(AtspiTextContext.on_text_context_changed  s
    ''))D,G,GG#M11//5578..t4""//$:J:JK ,2)T]Z! ' 224G#11W<  =#$**< %,"%)ZZHH,,_=r   r   r;   )T)0r=   r>   r?   r@   r   r   r^   r   rd   rf   rj   rl   r1   rt   rw   r4   r6   r}   r   r   r   r   rq   r   rn   r   r   r8   r   r:   r"   r-   r/   r'   r)   rb   r   r   r   r   r   r   r   r   r  r  r   r  r   r   r   rB   rB   Y   s     '(NG>./!:
, "+*+-'-,@>	8I,-
I(6+p"'K
6
/BH+GGr   rB   c                   l    e Zd ZdZd Zd Zd Zd Zd ZddZ	ddZ
d	 Zd
 Zd Zd Zed        Zd Zy)	InputLinea*  
    Track key presses ourselves.
    Advantage: Doesn't require AT-SPI
    Problems:  Misses key repeats,
               Doesn't know about keymap translations before events are
               delivered to their destination, i.e records wrong key
               strokes when changing keymaps.
    c                 $    | j                          y r   )r   r   s    r   r^   zInputLine.__init__F  s    

r   c                 <    d| _         d| _        d| _        i | _        y )NrD   r   T)liner   valid
word_infosr   s    r   r   zInputLine.resetI  s    	

r   c                     | j                   S r   )r  r   s    r   is_validzInputLine.is_validP      zzr   c                 2    t        | j                        dk(  S r{   )r   r  r   s    r   r   zInputLine.is_emptyS  s    499~""r   c                     | j                   d | j                   |z   | j                   | j                  d  z   | _         | j                  t        |             y r   )r  r   
move_caretr   )r   ss     r   r   zInputLine.insertV  sA    ii,q0499TZZ[3II	Ar   c                     | j                   d | j                  |z
   | j                   | j                  d  z   | _         | j                  |        y r   )r  r   r!  r   ns     r   delete_leftzInputLine.delete_leftZ  s>    IIotzzA~.4::;1GG	r   c                 z    | j                   d | j                   | j                   | j                  |z   d  z   | _         y r   r  r   r$  s     r   delete_rightzInputLine.delete_right^  s0    IIktzz*TYYtzzA~-GG	r   c                     | xj                   |z  c_         | j                   dk  rd| _         d| _        | j                   t        | j                        kD  r"t        | j                        | _         d| _        y y )Nr   F)r   r  r   r  r$  s     r   r!  zInputLine.move_careta  sY    

a
 ::>DJDJ::DII&TYYDJDJ 'r   c                 4    | j                   d | j                   S r   r(  r   s    r   r1   zInputLine.get_contextl  s    yy$**%%r   c                     | j                   S r   )r  r   s    r   r4   zInputLine.get_lineo  s    yyr   c                     | j                   S r   )r   r   s    r   r6   zInputLine.get_line_caret_posr  r  r   c                 <    | dk(  ryt        j                  |       dvS )zX
        True for printable keys including whitespace as defined for isprint().
        	T)CcCfCsCoCnZlZp)unicodedatacategory)chars    r   is_printablezInputLine.is_printableu  s.    
 4<''- 2D D 	Dr   c                    d}t         j                  j                  ry|j                  j	                         }|j                         }|t        |      dkD  rd}|j                  t        j                  k(  rnQ|j                  t        j                  k(  rn2|j                  t        j                  k(  rn|j                  t        j                  k(  r|dk(  r| j                          d}n|j                  t        j                  k(  rG|dk(  r| j                          n|dk(  r| j!                  d       n|d	k(  r| j!                  d       n}d}nz|j                  t        j"                  k(  r[|d
k(  rd}n|dk(  rd}n|dk(  rd}|dk(  r| j%                          n0| j'                  |      r|d   rd}n| j)                  |       nd}nd}| j+                         sd}|S )z|
        Sync input_line with single key presses.
        WORD_ACTION and MACRO_ACTION do this in press_key_string.
        FTr<   rD   ESCDELELEFTr   RGHTRTRN
SPCErp   TABr/  BKSP   )configr]   stealth_modeidupperr   r   action_typer   WORD_ACTIONMODIFIER_ACTIONBUTTON_ACTIONKEYSYM_ACTIONr   KEYPRESS_NAME_ACTIONr)  r!  KEYCODE_ACTIONr&  r:  r   r  )r   r   modsend_editingrH  r9  s         r   track_sent_keyzInputLine.track_sent_key  s   
 99!!VV\\^}}<3t9q=D??i333__	 9 99__	 7 77__	 7 77U{

K__	 > >>V|!!#v#v""__	 8 88V|vuV|  """4(7"&KKK%"K}}K r   Nr;   )r=   r>   r?   r@   r^   r   r  r   r   r&  r)  r!  r1   r4   r6   staticmethodr:  rS  r   r   r   r  r  <  sZ    # H	& D D?r   r  )%
__future__r   r   r   r7  r   logging	getLoggerr=   r   Onboard.Versionr   gi.repositoryr   ImportErroreOnboard.AtspiStateTrackerr   r	   Onboard.TextDomainr
   Onboard.TextChangesr   r   Onboard.utilsr   r   Onboard.Timerr   Onboardr   Onboard.Configr   rF  r   rB   r  r   r   r   <module>rc     s   ( B A   
'

H
% /  	# H 1 ; : + / "	'$ '$T`{ `FB By  		s   B B$B$