
,]c           @   s  d  Z  d d l Z d d l Z d d l m Z d d l m Z m Z m Z m	 Z	 m
 Z
 d d l m Z m Z d d l m Z m Z m Z m Z m Z m Z m Z d d l m Z d d l m Z m Z d d	 l m Z 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 e f d     YZ( d e f d     YZ) d e* f d     YZ+ d e e+ f d     YZ, d S(   s   
spyder.plugins
==============

Here, 'plugins' are widgets designed specifically for Spyder
These plugins inherit the following classes
(SpyderPluginMixin & SpyderPluginWidget)
iN(   t   PYQT5(   t   QEventt   QObjectt   QPointt   Qtt   Signal(   t   QCursort   QKeySequence(   t   QApplicationt   QDockWidgett   QMainWindowt	   QShortcutt   QTabBart   QWidgett   QMessageBox(   t   _(   t   get_color_schemet   get_font(   t   CONF(   t	   NoDefault(   t   configparsert   is_text_string(   t   icon_manager(   t   create_actiont   toggle_actionst	   TabFilterc           B   sq   e  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 RS(   s   
    Filter event attached to each QTabBar that holds 2 or more dockwidgets in
    charge of handling tab rearangement.

    This filter also holds the methods needed for the detection of a drag and
    the movement of tabs.
    c         C   s>   t  j |   | |  _ | |  _ t |  _ d  |  _ d  |  _ d  S(   N(	   R   t   __init__t   dock_tabbart   maint   Falset   movingt   Nonet
   from_indext   to_index(   t   selfR   R   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR   2   s    				c         C   sO   xH |  j  j D]: } |  j j |  j d d  } | j   | k r | Sq Wd S(   s(   Get plugin reference based on tab index.t   &t    N(   R   t
   widgetlistR   t   tabTextt   replacet   get_plugin_title(   R"   t   indext   plugint   tab_text(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   _get_plugin;   s    c         C   sF   g  } x9 t  |  j j    D]" } |  j |  } | j |  q W| S(   st   
        Get a list of all plugin references in the QTabBar to which this
        event filter is attached.
        (   t   rangeR   t   countR,   t   append(   R"   t   pluginsR)   R*   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   _get_pluginsB   s
    c         C   s  t  | |  | | } |  j j |  j   } |  j j |  j   } | | } |  j j | |  j   } | | } | d k r | | } n d } t   }	 |  j j |	 j    }
 |
 j   |
 j   } } | | k  s | | k r|  j j	 t
 | | |   } |	 j |  n  d S(   s<   Fix mouse cursor position to adjust for different tab sizes.i    N(   t   absR   t   tabRectt   widtht   xR   t   mapFromGlobalt   post   yt   mapToGlobalR   t   setPos(   R"   R    R!   t	   directiont	   tab_widtht	   tab_x_mint	   tab_x_maxt   previous_widtht   deltat   cursorR7   R5   R8   t   new_pos(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   _fix_cursorM   s    

	c         C   s   | j    } | t j k r, |  j |  t S| t j k rd y |  j |  Wn t k
 r_ n Xt S| t j	 k r |  j
 |  t St S(   s   Filter mouse press events.

        Events that are captured and not propagated return True. Events that
        are not captured and are propagated return False.
        (   t   typeR   t   MouseButtonPresst   tab_pressedR   t	   MouseMovet	   tab_movedt	   TypeErrort   Truet   MouseButtonReleaset   tab_released(   R"   t   objt   eventt
   event_type(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   eventFilterc   s    c         C   sv   |  j  j | j    |  _ |  j  j |  j  | j   t j k rr |  j d k rb |  j |  qr |  j	 |  n  d S(   s9   Method called when a tab from a QTabBar has been pressed.iN(
   R   t   tabAtR7   R    t   setCurrentIndext   buttonR   t   RightButtont   show_nontab_menut   show_tab_menu(   R"   RN   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyRF   x   s    c         C   s   | j    t j @s  d |  _ d S|  j j | j    |  _ |  j r |  j	 d k r |  j d k r t
 j t j  t |  _ n  |  j d k r |  j	 |  _ n  |  j	 |  j } } | | d d f k r |  j | |  |  j | |  | |  _	 n  d S(   s7   Method called when a tab from a QTabBar has been moved.Ni(   iN(   t   buttonsR   t
   LeftButtonR   R!   R   RQ   R7   R   R    R   t   setOverrideCursort   ClosedHandCursorRJ   t   move_tabRC   (   R"   RN   R    R!   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyRH      s    	(c         C   s   t  j   t |  _ d S(   s:   Method called when a tab from a QTabBar has been released.N(   R   t   restoreOverrideCursorR   R   (   R"   RN   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyRL      s    
c   	      C   s   |  j    } |  j |  } |  j |  } | j |  } | j |  } | | | | | | <| | <x= t t |  d  D]% } |  j j | | | | d  q| W| j j   d S(   s8   Move a tab from a given index to a given index position.i   N(	   R1   R,   R)   R-   t   lenR   t   tabify_pluginst
   dockwidgett   raise_(	   R"   R    R!   R0   t   from_plugint	   to_plugint   from_idxt   to_idxt   i(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR[      s    #c         C   s   |  j  |  d S(   s'   Show the context menu assigned to tabs.N(   RU   (   R"   RN   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyRV      s    c         C   s2   |  j  j   } | j |  j j | j     d S(   s2   Show the context menu assigned to nontabs section.N(   R   t   createPopupMenut   exec_R   R9   R7   (   R"   RN   t   menu(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyRU      s    (   t   __name__t
   __module__t   __doc__R   R,   R1   RC   RP   RF   RH   RL   R[   RV   RU   (    (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR   *   s   											t   SpyderDockWidgetc           B   s2   e  Z d  Z e   Z d   Z d   Z d   Z RS(   s#   Subclass to override needed methodsc         C   sK   t  t |   j | |  | |  _ | |  _ d  |  _ |  j j |  j	  d  S(   N(
   t   superRl   R   t   titleR   R   R   t   visibilityChangedt   connectt   install_tab_event_filter(   R"   Rn   t   parent(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR      s
    			c         C   s   |  j  j   d S(   s   
        Reimplement Qt method to send a signal on close so that "Panes" main
        window menu can be updated correctly
        N(   t   plugin_closedt   emit(   R"   RN   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt
   closeEvent   s    c         C   s   d } |  j j t  } xS | D]K } xB t | j    D]. } | j |  } | |  j k r8 | } Pq8 q8 Wq W| d k	 r | |  _ t	 |  j d d  d k r t
 |  j |  j  |  j _ |  j j |  j j  q n  d S(   s   
        Install an event filter to capture mouse events in the tabs of a
        QTabBar holding tabified dockwidgets.
        t   filterN(   R   R   t   findChildrenR   R-   R.   R&   Rn   R   t   getattrR   Rv   t   installEventFilter(   R"   t   valueR   t   tabbarst   tabbart   tabRn   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyRq      s    		(   Ri   Rj   Rk   R   Rs   R   Ru   Rq   (    (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyRl      s
   			t   SpyderPluginMixinc           B   sb  e  Z d  Z d Z d Z d Z d Z d Z e	 j
 Z e	 j Z e j e j BZ e 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  e! d  Z" d   Z# d   Z$ d   Z% d   Z& d   Z' e( d  Z) e! d  Z* d   Z+ d   Z, d d  Z- d   Z. d d  Z/ d   Z0 d   Z1 d   Z2 RS(   s5  
    Useful methods to bind widgets to the main window
    See SpyderPluginWidget class for required widget interface
    
    Signals:
        * sig_option_changed
             Example:
             plugin.sig_option_changed.emit('show_all', checked)
        * show_message
        * update_plugin_title
    i    t   imagesc         K   s   t  t |   j |   |  j d k	 s+ t  t j j t	 j
 |  j   |  _ | |  _ d |  _ d |  _ d |  _ d |  _ t |  _ t |  _ y  t j d d |  j  |  _ Wn t j k
 r d |  _ n Xd |  _ d S(   s%   Bind widget to a QMainWindow instancet	   shortcutss   _/switch to %sN(   Rm   R~   R   t   CONF_SECTIONR   t   AssertionErrort   ost   patht   dirnamet   inspectt   getfilet	   __class__t   PLUGIN_PATHR   t   default_marginst   plugin_actionsR_   t
   mainwindowR   t   ismaximizedt	   isvisibleR   t   gett   shortcutR   t   NoOptionErrort   toggle_view_action(   R"   R   t   kwds(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR      s     !							c         C   s   |  j    |  j   |  _ |  j d k	 r> |  j j |  j  n  |  j d k	 rc |  j j |  j  n  |  j	 d k	 r |  j	 j |  j
  n  |  j |  j    d S(   s6   Initialize plugin: connect signals, setup actions, ...N(   t   create_toggle_view_actiont   get_plugin_actionsR   t   show_messageR   Rp   t    _SpyderPluginMixin__show_messaget   update_plugin_titlet'   _SpyderPluginMixin__update_plugin_titlet   sig_option_changedt
   set_optiont   setWindowTitleR(   (   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   initialize_plugin  s    
c         C   s
   t   d S(   s3   Action to be performed on first plugin registrationN(   t   NotImplementedError(   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   on_first_registration'  s    c         C   sL   |  j  d t  rH y |  j   Wn t k
 r4 d SX|  j d t  n  d S(   s~   If this is the first time the plugin is shown, perform actions to
        initialize plugin position in Spyder's window layoutt
   first_timeN(   t
   get_optionRJ   R   R   R   R   (   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt&   initialize_plugin_in_mainwindow_layout0  s    c         C   s|   |  j    } |  j d  k r- | j   |  _ n  t j d d  rh t j d d  } | j | g d   n | j |  j   d  S(   NR   t   use_custom_margint   custom_margini   (   t   layoutR   R   t   getContentsMarginsR   R   t   setContentsMargins(   R"   R   t   margin(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   update_margins:  s    c         C   sQ   |  j  d k	 r |  j  } n |  j d k	 r6 |  j } n d S| j |  j    d S(   s8   Update plugin title, i.e. dockwidget or mainwindow titleN(   R_   R   R   R   R(   (   R"   t   win(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   __update_plugin_titleD  s    c         C   s   t  |  j   |  j  } | j |  j j d  | j |  j  | j |  j	  | j
 |   |  j   | j j |  j  | j j |  j  | |  _ |  j d k	 r t t |  j  |  j |  j  } |  j | d d |  j  n  | |  j f S(   s*   Add to parent QMainWindow as a dock widgett   _dwR   s   Switch to %sN(   Rl   R(   R   t   setObjectNameR   Ri   t   setAllowedAreast   ALLOWED_AREASt   setFeaturest   FEATURESt	   setWidgetR   Ro   Rp   t   visibility_changedRs   R_   R   R   R   R   t   switch_to_plugint   register_shortcutR   t   LOCATION(   R"   t   dockt   sc(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   create_dockwidgetN  s    
	c         C   s   t    |  _ } | j t j  |  j   } t |  rJ |  j |  } n  | j |  | j	 |  j
    | j |   |  j   | S(   sv   
        Create a QMainWindow instance containing this plugin
        Note: this method is currently not used
        (   R
   R   t   setAttributeR   t   WA_DeleteOnCloset   get_plugin_iconR   t   get_icont   setWindowIconR   R(   t   setCentralWidgett   refresh_plugin(   R"   R   t   icon(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   create_mainwindowi  s    
c         C   s3   |  j  d k	 r/ |  j  |  |  } | j   | Sd S(   s+   Create configuration dialog box page widgetN(   t   CONFIGWIDGET_CLASSR   t
   initialize(   R"   Rr   t   configwidget(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   create_configwidgety  s    
c         C   s
   t   d S(   s*   Apply configuration file's plugin settingsN(   R   (   R"   t   options(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   apply_plugin_settings  s    c         C   s   |  j  j | | | |  d S(   s   
        Register QAction or QShortcut to Spyder main application

        if add_sc_to_tip is True, the shortcut is added to the
        action's tooltip
        N(   R   R   (   R"   t   qaction_or_qshortcutt   contextt   namet   add_sc_to_tip(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR     s    c         C   s7   x0 | j    D]" \ } } } |  j | | |  q Wd S(   sr   
        Register widget shortcuts
        widget interface must have a method called 'get_shortcut_data'
        N(   t   get_shortcut_dataR   (   R"   t   widgett	   qshortcutR   R   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   register_widget_shortcuts  s    c         C   sv   |  j  j d k	 rC |  j  j j rC |  j  j |  k	 rC |  j  j   n  |  j j   se |  j j t  n  |  j	 t  d S(   s   Switch to plugin.N(
   R   t   last_pluginR   R   t   maximize_dockwidgetR   t	   isCheckedt
   setCheckedRJ   R   (   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR     s    c         C   s   | r; |  j  j   |  j   } | d k	 r; | j   q; n  |  j  j   pP |  j } |  j ro t |  j	 |  n  | ox | |  _
 |  j
 r |  j   n  d S(   s!   DockWidget visibility has changedN(   R_   R`   t   get_focus_widgetR   t   setFocust	   isVisibleR   t   DISABLE_ACTIONS_WHEN_HIDDENR   R   R   R   (   R"   t   enableR   t   visible(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR     s    		c         C   s   |  j  j t  d S(   s   DockWidget was closedN(   R   R   R   (   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyRs     s    c         C   s    t  j |  j t |  |  d S(   s   
        Set a plugin option in configuration file
        Use a SIGNAL to call it, e.g.:
        plugin.sig_option_changed.emit('show_all', checked)
        N(   R   t   setR   t   str(   R"   t   optionRz   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR     s    c         C   s   t  j |  j | |  S(   s+   Get a plugin option from configuration file(   R   R   R   (   R"   R   t   default(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR     s    c         C   s:   | r d } |  j  } n d } |  j } t d | d |  S(   s   
        Return plugin font option.

        All plugins in Spyder use a global font. This is a convenience method
        in case some plugins will have a delta size based on the default size.
        t	   rich_fontt   fontR   t   font_size_delta(   t   RICH_FONT_SIZE_DELTAt   FONT_SIZE_DELTAR   (   R"   t	   rich_textR   R   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   get_plugin_font  s    	c         C   s   t  d   d S(   s   
        Set plugin font option.

        Note: All plugins in Spyder use a global font. To define a different
        size, the plugin must define a 'FONT_SIZE_DELTA' class variable.
        sr   Plugins font is based on the general settings, and cannot be set directly on the plugin.This method is deprecated.N(   t	   Exception(   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   set_plugin_font  s    c         C   s   d S(   sa   
        This has to be reimplemented by plugins that need to adjust
        their fonts
        N(    (   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   update_font  s    c         C   s   |  j  j   j | |  d S(   s(   Show message in main window's status barN(   R   t	   statusBart   showMessage(   R"   t   messaget   timeout(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   __show_message  s    c         C   s1   |  j  |  t j t t j   t j   d S(   sp   
        Showing message in main window's status bar
        and changing mouse cursor to Qt.WaitCursor
        N(   R   R   RY   R   R   t
   WaitCursort   processEvents(   R"   R   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   starting_long_process  s    R$   c         C   s+   t  j   |  j | d d t  j   d S(   sV   
        Clearing main window's status bar
        and restoring mouse cursor
        R   i  N(   R   R\   R   R   (   R"   R   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   ending_long_process  s    
c         C   s   t  t j d d   S(   s   Get current color schemet   color_schemest   selected(   R   R   R   (   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR     s    c      	      s     j    }   j d k r* t d  } n    j d k	 rr t   | d   f d   d t   j  d t j } n t   | d   f d   } |   _	 d S(	   s/   Associate a toggle view action with each plugint   editort   Editort   toggledc            s     j  |   S(   N(   t   toggle_view(   t   checked(   R"   (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   <lambda>  R$   R   R   c            s     j  |   S(   N(   R   (   R   (   R"   (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR     s    N(
   R(   R   R   R   R   R   R   R   t   WidgetShortcutR   (   R"   Rn   t   action(    (   R"   s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR     s    c         C   sA   |  j  s d S| r0 |  j  j   |  j  j   n |  j  j   d S(   s   Toggle viewN(   R_   t   showR`   t   hide(   R"   R   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR     s    	N(3   Ri   Rj   Rk   R   R   R   R   R   t   IMG_PATHR   t   AllDockWidgetAreasR   t   LeftDockWidgetAreaR   R	   t   DockWidgetClosablet   DockWidgetFloatableR   RJ   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   Rs   R   R   R   R   R   R   R   R   R   R   R   R   (    (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR~      sN   						
	
	
				
		
										t   SpyderPluginWidgetc           B   s   e  Z d  Z e e e  Z e e e  Z e   Z	 e
 rE d   Z n	 d   Z d   Z d   Z d   Z e d  Z d   Z d   Z d	   Z d
   Z d   Z RS(   sn   
    Spyder base widget class
    Spyder's widgets either inherit this class or reimplement its interface
    c         K   sE   |  j    \ } } t t |   j | |  | sA |  j |  n  d  S(   N(   t   check_compatibilityRm   R  R   t   show_compatibility_message(   R"   Rr   R   R  R   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR      s    c         C   sL   |  j    \ } } t j |  |  t j |  |  | sH |  j |  n  d  S(   N(   R  R   R   R~   R  (   R"   Rr   R  R   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR   &  s
    c         C   s
   t   d S(   s   
        Return plugin title
        Note: after some thinking, it appears that using a method
        is more flexible here than using a class attribute
        N(   R   (   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR(   -  s    c         C   s   t  j d  S(   s   
        Return plugin icon (QIcon instance)
        Note: this is required for plugins creating a main window
              (see SpyderPluginMixin.create_mainwindow)
              and for configuration dialog widgets creation
        t   outline_explorer(   t   imaR   (   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR   5  s    c         C   s   d S(   sq   
        Return the widget to give focus to when
        this plugin's dockwidget is raised on top-level
        N(    (   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR   >  s    c         C   s   t  S(   s   
        Perform actions before parent main window is closed
        Return True or False whether the plugin may be closed immediately or not
        Note: returned value is ignored if *cancelable* is False
        (   RJ   (   R"   t
   cancelable(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   closing_pluginE  s    c         C   s
   t   d S(   s   Refresh widgetN(   R   (   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR   M  s    c         C   s
   t   d S(   s   
        Return a list of actions related to plugin
        Note: these actions will be enabled when plugin's dockwidget is visible
              and they will be disabled when it's hidden
        N(   R   (   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR   Q  s    c         C   s
   t   d S(   s'   Register plugin in Spyder's main windowN(   R   (   R"   (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   register_pluginY  s    c         C   s   d } t  } | | f S(   s   
        This method can be implemented to check compatibility of a plugin
        for a given condition.

        `message` should give information in case of non compatibility:
        For example: 'This plugin does not work with Qt4'
        R$   (   RJ   (   R"   R   t   valid(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR  ]  s    c         C   sd   t  |   } | j t j  | j t j  | j d  | j |  | j t  j	  | j
   d S(   s   Show compatibility message.s   Compatibility CheckN(   R   t   setWindowModalityR   t   NonModalR   R   R   t   setTextt   setStandardButtonst   OkR   (   R"   R   t
   messageBox(    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR  i  s    (   Ri   Rj   Rk   R   R   t   objectR   t   intR   R   R    R   R(   R   R   R   R	  R   R   R
  R  R  (    (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyR    s    										(-   Rk   R   R   t   qtpyR    t   qtpy.QtCoreR   R   R   R   R   t
   qtpy.QtGuiR   R   t   qtpy.QtWidgetsR   R	   R
   R   R   R   R   t   spyder.config.baseR   t   spyder.config.guiR   R   t   spyder.config.mainR   t   spyder.config.userR   t   spyder.py3compatR   R   t   spyder.utilsR   R  t   spyder.utils.qthelpersR   R   R   Rl   R  R~   R  (    (    (    s6   lib/python2.7/site-packages/spyder/plugins/__init__.pyt   <module>   s$   (4. 2