o
    `.                     @   s   d dl Z d dlZd dlZd dlZd dl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 dejZG dd deZdS )    N)Gdk)GLib)GObject)Gtk)log)xmlutil   )configc                   @   s  e Zd ZdZdZdZejjZe	dd Z
dd Zdd ZeeZd	d
 Zdd Zdd Zdd Ze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d8d%d&Zd'd( Zd9d*d+Zd,d- Z d.d/ Z!d0d1 Z"d2d3 Z#d4d5 Z$d6d7 Z%dS ):
vmmGObjectTNc                    s    fdd}t |S )z>
        Make sure idle functions are run thread safe
        c                      s    i S N r   argsfunckwargsr   0/usr/share/virt-manager/virtManager/baseclass.pycb*   s   zvmmGObject.idle_add.<locals>.cb)r   idle_add)r   r   r   r   r   r   r   r   %   s   
zvmmGObject.idle_addc                 C   sj   t j |  d| _g | _i | _g | _g | _i | _d| _t	| | _
tj r1| jr3| j| j
 d S d S d S )NFr   )r   __init___vmmGObject__cleaned_up_gobject_handles_gobject_handles_map_gobject_timeouts_gsettings_handles_signal_id_map_next_signal_idstr
object_keyr	   	vmmConfigis_initialized_leak_check
add_objectselfr   r   r   r   .   s   
zvmmGObject.__init__c                 C   s   ddl m} |j S Nr   )error) r%   vmmErrorDialogget_instancer#   r%   r   r   r   _get_errA   s   
zvmmGObject._get_errc                 C   s   | j rd S z^| jj| krd| j_| jjpi }t| D ]\}}|| kr)|| q|   | jd d  D ]}| 	| q5| j
d d  D ]}tj| |rR| | qD| jd d  D ]}| | qZW n tyr   td|  Y nw d| _ d S )NTError cleaning up %s)r   	__class__	_instance
_instanceslistitemspop_cleanupr   remove_gsettings_handler   r   handler_is_connected
disconnectr   remove_gobject_timeout	Exceptionr   	exception)r#   r.   kvhr   r   r   cleanupF   s0   


zvmmGObject.cleanupc                    s(   ddl m} | d fdd d S )Nr   )	vmmEnginezapp-closingc                    s      S r   )r<   )srcr"   r   r   <lambda>i   s    z2vmmGObject._cleanup_on_app_close.<locals>.<lambda>)enginer=   r(   connect)r#   r=   r   r"   r   _cleanup_on_app_closef   s   z vmmGObject._cleanup_on_app_closec                 C      t dNz(_cleanup must be implemented in subclassNotImplementedErrorr"   r   r   r   r2   k      zvmmGObject._cleanupc                 C   sT   zt j r| jr| j | j W d S W d S W d S  ty)   td| j Y d S w )NzError removing %s)	r	   r   r   r    remove_objectr   r7   r   r8   r"   r   r   r   __del__n   s   zvmmGObject.__del__c                 C   s
   t j S r   )r	   r   r(   r"   r   r   r   r	   u   s   
zvmmGObject.configc                 G   sb   t j j| ||g|R  }t|tjr)t|j}|| jvr!g | j|< | j| | | j	| |S )zk
        GObject connect() wrapper to simplify callers, and track handles
        for easy cleanup
        )
r   rA   
isinstancetypes
MethodTypeid__self__r   appendr   )r#   namecallbackr   retir   r   r   rA   }   s   


zvmmGObject.connectc                 C   s   t j | |}| j| |S )zB
        GObject disconnect() wrapper to simplify callers
        )r   r5   r   remove)r#   handlerR   r   r   r   r5      s   zvmmGObject.disconnectc                 C   sB   t |}| j|g D ]}|| jv r| | q| j|d dS )zW
        disconnect() every signal attached to a method of the passed instance
        N)rM   r   getr   r5   r1   )r#   instancerS   rU   r   r   r   disconnect_by_obj   s   

zvmmGObject.disconnect_by_objc                 G   s"   t j||g|R  }| | |S )zj
        GLib timeout_add wrapper to simplify callers, and track handles
        for easy cleanup
        )r   timeout_addadd_gobject_timeout)r#   timeoutr   r   rR   r   r   r   rY      s   
zvmmGObject.timeout_addc                 G   s2   |   std|  | | tjj| |g|R  S )z<
        GObject emit() wrapper to simplify callers
        zaemitting signal from non-main thread. This is a bug please report it. thread=%s self=%s signal=%s)_is_main_threadr   r%   _thread_namer   emit)r#   signal_namer   r   r   r   r^      s
   
zvmmGObject.emitc                 C      | j | d S r   )r   rO   r#   rU   r   r   r   add_gsettings_handle      zvmmGObject.add_gsettings_handlec                 C   s   | j | | j| d S r   )r	   remove_notifierr   rT   ra   r   r   r   r3      s   z"vmmGObject.remove_gsettings_handlec                 C   r`   r   )r   rO   ra   r   r   r   rZ      rc   zvmmGObject.add_gobject_timeoutc                 C   s   t | | j| d S r   )r   source_remover   rT   ra   r   r   r   r6      s   
z!vmmGObject.remove_gobject_timeoutc                 C   s,   t j|||pg |p
i d}d|_|  d S )N)targetrP   r   r   T)	threadingThreaddaemonstart)r#   rf   rP   r   r   tr   r   r   _start_thread   s
   zvmmGObject._start_threadc                 C   s
   t | S r   )sysgetrefcountr"   r   r   r   	_refcount      
zvmmGObject._refcountr&   c              
   C   s2   |r|d7 }t d|| j|  dt  d S )N z%s(%s %s)
:%sr&   )r   debugr   ro   join	tracebackformat_stack)r#   msgr   r   r   	_logtrace   s   zvmmGObject._logtracec                 C   s$   dd l }dd l}|||  d S Nr   )gcpprintget_referrers)r#   ry   rz   r   r   r   _gc_get_referrers   s   zvmmGObject._gc_get_referrersc                 C   s
   t  jS r   )rg   current_threadrP   r"   r   r   r   r]      rp   zvmmGObject._thread_namec                 C   s   |   dkS )N
MainThread)r]   r"   r   r   r   r\      s   zvmmGObject._is_main_threadc                    6   g  fdd}j ||g|R  }| |S )zr
        Like standard glib connect(), but only runs the signal handler
        once, then unregisters it
        c                     s   r	 d   |  S rx   r5   )wrapargsr   id_listr#   r   r   	wrap_func   s   z*vmmGObject.connect_once.<locals>.wrap_funcrA   rO   r#   signalr   r   r   conn_idr   r   r   connect_once   s
   
zvmmGObject.connect_oncec                    r   )z}
        Like standard glib connect(), but allows the signal handler to
        unregister itself if it returns True
        c                     s*    |  }|rr d  d S d S d S rx   r   )r   rR   r   r   r   r      s   z-vmmGObject.connect_opt_out.<locals>.wrap_funcr   r   r   r   r   connect_opt_out   s
   
zvmmGObject.connect_opt_outc                    s$    fdd} j ||g|R   dS )zG
        Safe wrapper for using 'self.emit' with GLib.idle_add
        c                    s    j | g|R   dS )NF)r^   )_s_ar"   r   r   emitwrap  s   z&vmmGObject.idle_emit.<locals>.emitwrapN)r   )r#   r   r   r   r   r"   r   	idle_emit
  s   zvmmGObject.idle_emit)NNNN)r&   )&__name__
__module____qualname__r    r-   r.   r   SignalFlags	RUN_FIRSTstaticmethodr   r   r*   propertyerrr<   rB   r2   rI   r	   rA   r5   rX   rY   r^   rb   r3   rZ   r6   rl   ro   rw   r|   r]   r\   r   r   r   r   r   r   r   r
      sD    
 

	


r
   c                   @   sz   e Zd ZdddZdd ZeeZ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dZdd ZdS )vmmGObjectUINc                 C   s   t |  t|| _d| _|r<tj| j	 |}t
 | _| jd | j| |s8| || _| j  n
|| _n|| _|| _d | _d S )NFzvirt-manager)r
   r   bool_external_topwin_vmmGObjectUI__cleaned_upospathrs   r	   
get_ui_dirr   Builderbuilderset_translation_domainadd_from_filewidgettopwinhide_err)r#   filename
windownamer   r   uifiler   r   r   r     s   



zvmmGObjectUI.__init__c                 C   s*   | j d u rddlm} || j| _ | j S r$   )r   r&   r%   r'   r   r)   r   r   r   r*   -  s   
zvmmGObjectUI._get_errc                 C   s"   | j |}|std| |S )NzDid not find widget name=%s)r   
get_objectr   DevError)r#   rP   rR   r   r   r   r   4  s   zvmmGObjectUI.widgetc                 C   sl   | j rd S z|   t|  d | _| js| j  d | _d | _W n t	y0   t
d|  Y nw d| _ d S )Nr+   T)r   closer
   r<   r   r   r   destroyr   r7   r   r8   r"   r   r   r   r<   :  s   



zvmmGObjectUI.cleanupc                 C   rC   rD   rE   r"   r   r   r   r2   K  rG   zvmmGObjectUI._cleanupc                 C   s   d S r   r   )r#   ignore1ignore2r   r   r   r   N  s   zvmmGObjectUI.closec                 C   s   t | jo| j S r   )r   r   get_visibler"   r   r   r   
is_visibleQ  s   zvmmGObjectUI.is_visiblec                    s    fdd} j d| d S )Nc                    s    t |jdkr   d S d S )NEscape)r   keyval_namekeyvalr   )
src_ignoreeventr"   r   r   close_on_escapeU  s   z;vmmGObjectUI.bind_escape_key_close.<locals>.close_on_escapezkey-press-event)r   rA   )r#   r   r   r"   r   bind_escape_key_closeT  s   z"vmmGObjectUI.bind_escape_key_closec                 C   sZ   | j  }|s	d S ztj| |}|| W d S  ty,   tj	d|dd Y d S w )NzError setting cursor_type=%sT)exc_info)
r   
get_windowr   Cursornew_from_nameget_display
set_cursorr7   r   rr   )r#   cursor_type
gdk_windowcursorr   r   r   _set_cursorZ  s   
zvmmGObjectUI._set_cursorc                 C   s   | j d | d d S )NFprogressr   set_sensitiver   r"   r   r   r   set_finish_cursori  s   zvmmGObjectUI.set_finish_cursorc                 C   s"   |s| j }|d | d d S )NTdefaultr   )r#   r   r   r   r   reset_finish_cursorm  s   
z vmmGObjectUI.reset_finish_cursorc                    s0   ddl m} | } fdd}|d| d S )Nr   )vmmConnectionManagerc                    s0   t  dd }|r| |kr   dS d S d S )NconnT)getattrget_urir<   )_srcuri_connr"   r   r   _cbw  s
   z2vmmGObjectUI._cleanup_on_conn_removed.<locals>._cbzconn-removed)connmanagerr   r(   r   )r#   r   r   r   r   r"   r   _cleanup_on_conn_removeds  s   z%vmmGObjectUI._cleanup_on_conn_removed)NNr   )r   r   r   r   r*   r   r   r   r<   r2   r   r   r   r   r   r   r   r   r   r   r   r     s    


r   )r   rm   rg   rt   rK   gi.repositoryr   r   r   r   virtinstr   r   r&   r	   r
   r   r   r   r   r   <module>   s    ~