
    ujC                         d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	 ddl
mZmZmZ ddlmZmZmZmZmZmZmZ 	 ddlZeegdf   Zeegdf   Zeg ef   Ze G d d	             Z G d
 d      Z y# e$ r dZY :w xY w)u<  yjm_clipboard_sync.py

텍스트 클립보드 동기화 보조 모듈.

현재 단계(v2.9):
- 자동 양방향 동기화는 하지 않는다.
- viewer가 명시적으로 요청하면 host PC 클립보드 텍스트를 viewer로 보낸다.
- viewer에서 보낸 텍스트를 host PC 클립보드에 넣는다.
- 이미지/파일 클립보드는 아직 다루지 않는다.
- 브라우저 보안 정책 때문에 viewer 쪽 자동 클립보드 쓰기는 실패할 수 있다.
  실패하면 viewer.html에서 복사 버튼/텍스트 상자로 수동 복사하도록 한다.
    )annotationsN)	dataclass)CallableOptional)preview_text	read_text
write_text)LEGACY_MSG_CLIPBOARDMSG_CLIPBOARD_DATAMSG_CLIPBOARD_GETMSG_CLIPBOARD_SET	MSG_ERRORMSG_LOGmake_msgc                  &    e Zd ZU ded<   dZded<   y)ClipboardResultboolok strmessageN)__name__
__module____qualname____annotations__r        )D:\_St\RTC8790_8791\yjm_clipboard_sync.pyr   r   +   s    HGSr   r   c                      e Zd ZdZddddddd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ddZddZeddd       Zy)ClipboardSyncManageru2   Tk clipboard 기반 텍스트 동기화 관리자.Ni  i@ F)is_enabled_callbacknotify_viewers_callbackstatus_callbackloggerpoll_ms	max_chars	auto_syncc                  || _         |xs d | _        || _        || _        || _        t        dt        |            | _        t        dt        |            | _        t        |      | _
        d | _        d | _        d| _        d| _        y )Nc                      yNFr   r   r   r   <lambda>z/ClipboardSyncManager.__init__.<locals>.<lambda>A   s    5r   i,  i  Fg        )rootr!   r"   r#   r$   maxintr%   r&   r   r'   
_last_text_last_set_from_remote_polling_last_notice_at)	selfr,   r!   r"   r#   r$   r%   r&   r'   s	            r   __init__zClipboardSyncManager.__init__4   s|     	#6#I= '>$.3G-T3y>2i&*15""r   c                T    	 t        | j                               S # t        $ r Y yw xY wr*   )r   r!   	Exceptionr3   s    r   
is_enabledzClipboardSyncManager.is_enabledM   s-    	00233 		s    	''c                    | j                   sd| _        y | j                  ry d| _        | j                  j                  | j                  | j
                         y )NFT)r'   r1   r,   afterr%   
_poll_oncer7   s    r   startzClipboardSyncManager.startS   s@     ~~!DM==		doo6r   c                    d| _         y r*   )r1   r7   s    r   stopzClipboardSyncManager.stop^   s	    r   c           
         |rdnd}| j                  t        t        ddt        |      ||rdnd             | j                  r	 | j	                  |rd       y d	       y y # t
        $ r Y y w xY w)
Nenableddisabled	clipboardstateu!   클립보드 수동 전송 허용u!   클립보드 수동 전송 차단)sourceactionr@   rC   r   u,   원격: 클립보드 수동 전송
허용됨u,   원격: 클립보드 수동 전송
차단됨)_notifyr   r   r   r#   r6   )r3   r@   rC   s      r   notify_statez!ClipboardSyncManager.notify_statea   s    $	*XM;B7Hk
 	 $$X_%T  V  fU  V    s   A! A! !	A-,A-c                X    	 t        j                  |      }t	        |t
              st        dd      S |j                  d      xs d}|j                  d      xs d}|t        k(  xs |t        k(  xr |dv }|t        k(  xs |t        k(  xr |dk(  }|r j                         st        dd      S |j                  d	      }|d}t	        |t              st        |      }t        |       j                  kD  r|d
 j                   } j                  j                  d|f fd	       t        dd      S |rN j                         st        dd      S  j                  j                  d j                          t        dd      S t        dd      S # t        $ r t        dd      cY S w xY w)ur  WebSocket text JSON 중 clipboard 관련 메시지만 처리한다.

        v3 표준 타입:
        - clipboard_set: viewer -> host 텍스트 설정
        - clipboard_get: viewer -> host 현재 클립보드 요청

        v2 호환 타입:
        - {type:"clipboard", action:"viewer_to_host"}
        - {type:"clipboard", action:"request_host_clipboard"}
        Fignoredtyper   rE   )viewer_to_hostset_hostrequest_host_clipboardzhost clipboard sync disabledtextNr   c                &    j                  |       S N)_set_host_clipboard)tr3   s    r   r+   z:ClipboardSyncManager.handle_text_message.<locals>.<lambda>   s    d.F.Fq.Ir   Tzclipboard set scheduledzclipboard request scheduled)jsonloadsr6   r   
isinstancedictgetr   r
   r   r8   r   lenr&   r,   r:   _send_current_clipboard)r3   r   datamsg_typerE   is_setis_getrN   s   `       r   handle_text_messagez(ClipboardSyncManager.handle_text_messageq   s   	5::g&D $%"5)4488F#)r(#)r..  B8?S3S  4AX^  cA  YA..{8?S3S3zX^bzXz??$&u.LMM88F#D|dC(4y4y4>>),dnn-IIOOAIJ"4)BCC??$&u.LMMIIOOAt;;<"4)FGGui00?  	5"5)44	5s   F F)(F)c                D    t        | j                  | j                        S )Nr&   )r   r,   r&   r7   s    r   _read_clipboard_textz)ClipboardSyncManager._read_clipboard_text   s    dnn==r   c                ^   	 t        || j                  | j                        }|| _        || _        | j                  t        t        ddd| d|| j                  |                   | j                  r#| j                  d| j                  |              | j                  r| j                  j                  d|       y y # t        $ ra}| j                  t        t        dt        |      	             | j                  r!| j                  j                  d
|       Y d }~y Y d }~y d }~ww xY w)Nr`   rB   ack_host_setu!   host 클립보드 적용 완료 (u   자))rD   rE   r   lengthpreviewu   원격: 클립보드 수신
z(clipboard received from viewer: %d charsrD   r   zclipboard set error: %s)r	   r,   r&   r/   r0   rF   r   r   _previewr#   r$   infor6   r   r   error)r3   rN   writtenexcs       r   rQ   z(ClipboardSyncManager._set_host_clipboard   s    	B tyyDNNKG"DO)-D&LL"%;G9DId+  ##$$'DT]]SWEXDY%Z[{{  !KWU  	BLL)KSRS{{!!";SAA 	Bs   B>C 	D,AD''D,c                    | j                         }|"| j                  t        t        dd             y || _        | j                  |d       y )NrB   zhost clipboard has no textrf   requestreason)ra   rF   r   r   r/   _notify_host_text)r3   rN   s     r   rY   z,ClipboardSyncManager._send_current_clipboard   sH    ((*<LL)KIefgtI6r   c                0   | j                   sy 	 | j                         r;| j                         }|)|| j                  k7  r|| _        | j	                  |d       | j                   r1| j                  j                  | j                  | j                         y y # t
        $ r2}| j                  r| j                  j                  d|       Y d }~td }~ww xY w# | j                   r1| j                  j                  | j                  | j                         w w xY w)Nchangedrn   zclipboard poll error: %s)r1   r8   ra   r/   rp   r6   r$   debugr,   r:   r%   r;   )r3   rN   rk   s      r   r;   zClipboardSyncManager._poll_once   s    }}	? 002#(?&*DO**4	*B
 }}		doo> 	  	C{{!!"<cB	C }}		doo> s*   AB 	C!(C	C CC ?Dc               V   | j                  t        t        ||t        |      | j	                  |                   t        j
                         }| j                  r?|| j                  z
  dkD  r,|| _        	 | j                  d| j	                  |              y y y # t        $ r Y y w xY w)N)ro   rN   rd   re   g333333?u   원격: 클립보드 전송
)	rF   r   r   rX   rg   timer#   r2   r6   )r3   rN   ro   nows       r   rp   z&ClipboardSyncManager._notify_host_text   s    Xt9MM$'
 	 iikC$*>*>$>$D#&D $$'DT]]SWEXDY%Z[ %E  s   6#B 	B('B(c                `    | j                   r	 | j                  |       y y # t        $ r Y y w xY wrP   )r"   r6   )r3   payloads     r   rF   zClipboardSyncManager._notify   s7    '',,W5 (  s   ! 	--c                    t        | |      S )N)limit)r   )rN   rz   s     r   rg   zClipboardSyncManager._preview   s    D..r   )r!   zOptional[EnabledCallback]r"   zOptional[NotifyCallback]r#   zOptional[StatusCallback]r%   r.   r&   r.   r'   r   )returnr   )r{   None)r@   r   r{   r|   )r   r   r{   r   )r{   z
str | None)rN   r   r{   r|   )rN   r   ro   r   r{   r|   )rx   rV   r{   r|   )*   )rN   r   rz   r.   r{   r   )r   r   r   __doc__r4   r8   r<   r>   rG   r^   ra   rQ   rY   r;   rp   rF   staticmethodrg   r   r   r   r    r    1   s    < :><@48 # 7	#
 ":# 2# # # #2	7 ,1\>B,7?   / /r   r    )!r~   
__future__r   rS   ru   dataclassesr   typingr   r   host.clipboardr   r   r	   host.protocolr
   r   r   r   r   r   r   tkintertkr6   rV   NotifyCallbackr   StatusCallbackr   EnabledCallbackr   r    r   r   r   <module>r      s    #   ! % > >   4&$,'3%+&2t8$   
x/ x/  	Bs   A1 1A;:A;