
    b_                        d Z ddlZddlZddlZddlZddlZ	 ddlmc mZ ddlmZmZ ddlmZ ddlmZ ddlmZ ddlZddlZd Zd Zd	Zd
ZdZdZdZdZ G d d      Z  G d d      Z! G d d      Z" G d d      Z# G d d      Z$ G d d      Z% G d d      Z&d\  Z'Z(d Z)d Z*d  Z+d! Z, G d" d#e-      Z. G d$ d%      Z/d'd&Z0y# e	$ r ddl
mc mZ Y w xY w)(a  
Implementation of the XDG Menu Specification
http://standards.freedesktop.org/menu-spec/

Example code:

from xdg.Menu import parse, Menu, MenuEntry

def print_menu(menu, tab=0):
  for submenu in menu.Entries:
    if isinstance(submenu, Menu):
      print ("	" * tab) + unicode(submenu)
      print_menu(submenu, tab+1)
    elif isinstance(submenu, MenuEntry):
      print ("	" * tab) + unicode(submenu.DesktopEntry)

print_menu(parse())
    N)xdg_data_dirsxdg_config_dirs)DesktopEntry)ParsingError)PY3c                    t         j                  dk\  rRt        j                  |       } t         j                  dk\  rt        j                  |       S t        j
                  |       S t        j                  | t        j                               S )N)      )r	      idctx)sysversion_infoastliteral_evalConstantNameConstantNameLoad)names    (lib/python3.12/site-packages/xdg/Menu.py
_ast_constr   '   se    
6!%v%<<%%##D))xx4SXXZ00    c                 z    t         s!t        | t              r| j                  d      } t	        j
                  |       S )zgWrapper around locale.strxfrm that accepts unicode strings on Python 2.

    See Python bug #2481.
    zutf-8)r   
isinstanceunicodeencodelocalestrxfrm)ss    r   _strxfrmr"   2   s-    
 Z7+HHW>>!r   Deleted	NoDisplayHiddenEmpty	NotShowInNoExecc                       e 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dZd Zd Zd Zd Zd Z	 d Zd Zy)Menuz^Menu containing sub menus under menu.Entries

    Contains both Menu and MenuEntry items.
    c                 *   d| _         d | _        g | _        d| _        d| _        d| _        d | _        d| _        d| _        d| _	        g | _
        d | _        d | _        g | _        g | _        d | _        g | _        g | _        d | _        g | _        g | _        y )N r   FT)r   	DirectoryEntriesDocFilenameDepthParentNotInXmlShowVisibleAppDirsDefaultLayoutr#   DirectoriesDirectoryDirsLayoutMenuEntriesMovesOnlyUnallocatedRulesSubmenusselfs    r   __init__zMenu.__init__I   s    	
 	 !
#
r   c                     | j                   S Nr   r@   s    r   __str__zMenu.__str__e       yyr   c                    |j                   D ]  }| j                   j                  |        |j                  D ]  }| j                  j                  |        |j                  D ]  }| j                  j                  |        |j                  |j                  | _        |j
                  |j
                  | _        |j                  r|j                  | _        |j                  r|j                  | _        |j                  D ]  }| j                  j                  |        |j                  D ]  }| j                  j                  |        |j                  D ]  }| j                  |        | S rD   )r6   appendr9   r8   r#   r=   r:   r7   r>   r<   r?   
addSubmenu)rA   otherdir	directoryrulemovesubmenus          r   __add__zMenu.__add__h   s-   ==CLL$ ! &&C%%c* ' **I##I. + ==$ ==DL  ,#(#8#8D <<,,DK!&!4!4DKKDJJd#   KKDJJd#   ~~GOOG$ & r   c                 f    t        j                  | j                         |j                               S rD   )r   strcollgetNamerA   rK   s     r   __cmp__zMenu.__cmp__   s    ~~dllnemmo>>r   c                 4    t        | j                               S z&Key function for locale-aware sorting.)r"   rT   r@   s    r   _keyz	Menu._key   s    ''r   c                 h    	 |j                         }| j                         |k  S # t        $ r Y w xY wrD   rY   AttributeErrorrU   s     r   __lt__zMenu.__lt__   9    	JJLE yy{U""  		   % 	11c                     	 | j                   t        |      k(  S # t        $ r | j                   t        |      k(  cY S w xY wrD   )r   r   	NameErrorstrrU   s     r   __eq__zMenu.__eq__   s<    	+99.. 	+99E
**	+s    !>>c              #   b   K   | j                   D ]  }|r| 
|j                  du s|  yw)z4Interator for a list of Entries visible to the user.TN)r.   r4   )rA   show_hiddenentrys      r   
getEntrieszMenu.getEntries   s-     \\Et#	 "s   %//c                     | j                   D ]  }|j                  |k(  s|c S  |r$| j                  D ]  }|j                  ||        yy)z4Searches for a MenuEntry with a given DesktopFileID.N)r;   DesktopFileIDr?   getMenuEntry)rA   desktopfileiddeep	menuentryrP   s        r   rj   zMenu.getMenuEntry   sN    ))I&&-7   * ==$$]D9 ) r   c                     |j                  dd      }| j                  D ]<  }|j                  |d   k(  st        |      dkD  r|j	                  |d         c S |c S  y)z&Searches for a Menu with a given path./   r   N)splitr?   r   lengetMenu)rA   patharrayrP   s       r   rs   zMenu.getMenu   sS    

3"}}G||uQx'u:>"??5844"N %r   c                 ^   | }g }	 |r|j                  |j                         n|j                  |j                                |j                  dkD  r|j                  }nn[|j                          d}|s|j                  d       |D ]"  }t        j                  j                  ||      }$ |S )z/Returns this menu's path in the menu structure.r   r,   )
rI   r   rT   r1   r2   reversepoposrt   join)rA   orgtoplevelparentnamesrt   r   s          r   getPathzMenu.getPath   s    V[[)V^^-.||a  	IIaLD77<<d+D r   c                     	 | j                   j                  j                         S # t        $ r | j                  cY S w xY w)z"Returns the menu's localised name.)r-   r   rT   r\   r   r@   s    r   rT   zMenu.getName   s9    	>>..6688 	99	s   #& >>c                 j    	 | j                   j                  j                         S # t        $ r Y yw xY w)z Returns the menu's generic name.r,   )r-   r   getGenericNamer\   r@   s    r   r   zMenu.getGenericName   s2    	>>..==?? 		   #& 	22c                 j    	 | j                   j                  j                         S # t        $ r Y yw xY w)z Returns the menu's comment text.r,   )r-   r   
getCommentr\   r@   s    r   r   zMenu.getComment   s2    	>>..99;; 		r   c                 j    	 | j                   j                  j                         S # t        $ r Y yw xY w)z0Returns the menu's icon, filename or simple namer,   )r-   r   getIconr\   r@   s    r   r   zMenu.getIcon   s2    	>>..6688 		r   c                    g | _         d| _        | j                  D ]  }|j                           t	               }t	               }| j
                  j                  D ]<  }|d   dk(  r|j                  |d           |d   dk(  s)|j                  |d          > | j
                  j                  D ]  }|d   dk(  rct        |       }t        | j                         dkD  r$t        | j                   d   t              rd|_        | j                   j                  |       o|d   dk(  r3| j                  |d         }|s| j                   j                  |       |d   dk(  r\| j                  |d         }|s|j
                  j                  r| j!                  |       | j                   j                  |       |d   dk(  s|d   d	k(  s|d   d
k(  rW| j"                  j                          | j"                  D ],  }|j$                  |vs| j                   j                  |       . |d   dk(  s
|d   d
k(  s| j                  j                          | j                  D ]T  }|j&                  |vs|j
                  j                  r| j!                  |       :| j                   j                  |       V  | j                   D ]  }d|_        | xj                  dz  c_        t        |t(              r|j*                  du r!t,        |_        | xj                  dz  c_        _t        |j.                  t0              sz|j.                  j2                  j5                         r!t6        |_        | xj                  dz  c_        |j.                  j2                  j9                         st:        |_        | xj                  dz  c_        t        |t0              r|j2                  j5                         r"t6        |_        | xj                  dz  c_        S|j2                  j9                         r"t:        |_        | xj                  dz  c_        |j2                  j=                         r<|j2                  j?                         s"t@        |_        | xj                  dz  c_        tB        jD                  jF                  s|j2                  jI                         g k7  r4tB        jD                  jF                  |j2                  jI                         vs6tB        jD                  jF                  |j2                  jK                         v stL        |_        | xj                  dz  c_        t        |t              s| xj                  dz  c_         t        | j                         dkD  r1t        | j                   d   t              rd| j                   d   _        t        | j                         dkD  r1t        | j                   d   t              rd| j                   d   _        | j                   d d  D ]  }t        |t(              s|j
                  jN                  r+|j                  dk(  s;tP        |_        | xj                  dz  c_        |jR                  du sj| j                   jU                  |        y )Nr   r0   rp   Menuname	SeparatorFMergefilesallmenusT)+r.   r5   r?   sortsetr:   orderaddr   rr   r   r4   rI   rj   rs   inlinemerge_inliner;   ri   r   r*   r#   DELETEDr-   	MenuEntryr   getNoDisplay
NO_DISPLAY	getHiddenHIDDEN
getTryExecfindTryExecNO_EXECxdgConfigwindowmanagergetOnlyShowIngetNotShowInNOT_SHOW_IN
show_emptyEMPTYr3   remove)rA   rP   	_submenus_entriesr   	separatorrm   rf   s           r   r   z	Menu.sort   s   }}GLLN % E	5[[&&EQx:%U1X&qZ'eAh'	 ' [[&&EQx;&%dO	t||$q(ZR8H)-T%*IN##I.qZ' --eAh7	LL''	2qZ',,uQx0~~,,))'2++G4qW$8w&%(e*;$$))+%)%5%5	$22(B LL//	: &6 1X(E!H,=MM&&(#'=="<<y8&~~44 $ 1 1' : $ 3 3G < $13 'B \\EEJLLAL%&==D(!(EJLLA%L;33@@B%/
)55??A%+
)E9-%%224!+EJLLA%L''113!'EJLLA%L''224U=O=O=[=[=]!(EJLLA%LZZ--**88:b@JJ44E<N<N<\<\<^^ 

00E4F4F4S4S4UU%0
)E9-!E "H t||q $,,q/95',Q$t||q $,,r*I6(-R % \\!_E%&u||/F/F5==\]K]"
!>>T)LL''. %r   c                     | j                   D ]  }||k(  s	||z  } y  | j                   j                  |       | |_        | j                  dz   |_        y )Nrp   )r?   rI   r2   r1   )rA   newmenurP   s      r   rJ   zMenu.addSubmenuT  sO    }}G'!7" %
 MM  )!GN JJNGMr   c                    t        |j                        dk(  r|j                  j                  r|j                  d   }|j                  j                  d|j                         d       |j                  j                  d|j                         d       |j                  j                  d|j                         d       | j                  j                  |       yt        |j                        |j                  j                  k  s|j                  j                  dk(  r|j                  j                  rRt        |j                         |j                         |j                               }| j                  j                  |       |j                  D ]  }| j                  j                  |        y| j                  j                  |       y)	z}Appends a submenu's entries to this menu
        See the <Menuname> section of the spec about the "inline" attribute
        rp   r   r   T)r   GenericNameCommentN)rr   r.   r:   inline_aliasr   r   rT   r   r   rI   inline_limitinline_headerHeader)rA   rP   rm   headerrf   s        r   r   zMenu.merge_inline_  sS    w1$)D)D*I""&&vw/@&N""&&}g6L6L6NW[&\""&&y'2D2D2Ft&TLL	*!W^^%@%@@GNND_D_cdDd~~++ 173I3I3KWM_M_Mab##F+ ##E* ) LL(r   NF)FF)__name__
__module____qualname____doc__rB   rF   rQ   rV   rY   r]   rc   rg   rj   rs   r   rT   r   r   r   r   rJ   r    r   r   r*   r*   D   sn    8D?(#+ :#*b/H +)r   r*   c                       e Zd ZdZddZd Zy)MovezA move operationc                      || _         || _        y rD   )OldNew)rA   oldnews      r   rB   zMove.__init__u  s    r   c                 B    t        | j                  |j                        S rD   )cmpr   rU   s     r   rV   zMove.__cmp__y  s    488UYY''r   Nr,   r,   )r   r   r   r   rB   rV   r   r   r   r   r   s  s    (r   r   c                   P    e Zd ZdZ	 	 ddZed        Zej                  d        Zy)r:   zMenu Layout classc                 r    || _         || _        || _        || _        || _        g | _        ddgddgg| _        y )Nr   r   r   )r   r   r   r   r   _order_default_order)rA   r   r   r   r   r   s         r   rB   zLayout.__init__  sI    $(*(gg
r   c                 J    | j                   r| j                   S | j                  S rD   )r   r   r@   s    r   r   zLayout.order  s    "kkt{{Bt/B/BBr   c                     || _         y rD   )r   )rA   r   s     r   r   zLayout.order  s	    r   N)FFr
   TF)r   r   r   r   rB   propertyr   setterr   r   r   r:   r:   }  s>    DE27
 C C \\ r   r:   c                   <    e Zd ZdZd\  ZZed        Zd Zd Z	d Z
y)RulezInclude / Exclude Rules Classr   rp   c                    t        j                  t        j                  t        j                  |      t        j                         gt        j
                  t        j                  dt        j                               dt        j                               g      dd      }t        j                  |       t        ||      }|S )	Nrm   r   ri   valueattrr   leftopscomparatorsrp   r   )bodylineno
col_offset)
r   
ExpressionCompareStrEq	Attributer   r   fix_missing_locationsr   )clstypefilenametreerN   s        r   fromFilenamezRule.fromFilename  s    ~~WWX&VVXJ ]]((ksxxzB(
  
 	!!$'D$r   c                 X    || _         || _        t        | j                  dd      | _        y )Nz<compiled-menu-rule>eval)Type
expressioncompilecode)rA   r   r   s      r   rB   zRule.__init__  s%    	$DOO-CVL	r   c                 @    t        j                  | j                        S rD   )r   dumpr   r@   s    r   rF   zRule.__str__  s    xx((r   c                     |D ]l  }|dk(  r|j                   du s|j                  du r%t        | j                        s;| j                  t
        j                  u rd|_        d|_         fd|_        n |S )N   TF)MatchedInclude	Allocatedr   r   r   r   TYPE_INCLUDEAdd)rA   menuentriesrunrm   s       r   applyz
Rule.apply  sl    $IaxY55=&00D8DII99 1 11$(IM/3I,$)IM % r   N)r   r   r   r   r   TYPE_EXCLUDEclassmethodr   rB   rF   r   r   r   r   r   r     s1    '!%L, "M)r   r   c                   h    e Zd ZdZdZdZdZd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y)r   z(Wrapper for 'Menu Style' Desktop EntriesUserSystemBothc                    t        t        j                  j                  ||            | _         | j	                  |||       d| _        d | _        g | _        d| _        d| _	        d| _
        | j                   j                         | _        y NTF)r   ry   rt   rz   setAttributesr4   OriginalParentsr   r   r   getCategories
CategoriesrA   r   rL   prefixs       r   rB   zMenuEntry.__init__  sy    (c8)DE8S&1 	  # ++99;r   c                 f    | j                   j                  r| j                   j                          yy)z&Save any changes to the desktop entry.N)r   taintedwriter@   s    r   savezMenuEntry.save  s(    $$##% %r   c                 b    | j                   j                  j                  | j                  d      S )z7Return the directory containing the desktop entry file.r,   )r   r   replacer0   r@   s    r   getDirzMenuEntry.getDir  s%      ))11$--DDr   c                     t         j                  j                  sO| j                  r| j                  S t
        d   | j                  j                  v r| j                  S | j                  S | j                  S )z.Return the type of MenuEntry, System/User/Bothr   )
r   r   	root_moder   	TYPE_BOTHr   r   r   	TYPE_USERTYPE_SYSTEMr@   s    r   getTypezMenuEntry.getType  sY    zz##}}~~%q!T%6%6%?%??~~%'''>>!r   c                    || _         || _        t        j                  j	                  ||      j                  dd      | _        t        j                  j                  | j                  j                        s| j                          y y )Nro   -)r0   Prefixry   rt   rz   r  ri   isabsr   r   _MenuEntry__setFilenamer  s       r   r   zMenuEntry.setAttributes  sa     WW\\&(;CCCMww}}T..778  9r   c                     | j                         | j                  k(  rEt        | j                  | j	                         | j
                        | _        | j                          y y rD   )r  r  r   r0   r  r  r   r  r@   s    r   updateAttributeszMenuEntry.updateAttributes  sE    <<>T---%dmmT[[]DKKPDM  .r   c                    t         j                  j                  s
t        d   }n	t        d   }| j                  j                         dk(  r!t        j                  j                  |d      }n t        j                  j                  |d      }t        j                  j                  || j                        | j                  _
        y )Nr   rp   Applicationapplicationsdesktop-directories)r   r   r  r   r   r  ry   rt   rz   r0   r   )rA   rt   dir_s      r   __setFilenamezMenuEntry.__setFilename  s    zz## #D #D$$&-777<<n5D77<<&;<D%'WW\\$%F"r   c                     t        j                  | j                  j                         |j                  j                               S rD   )r   rS   r   rT   rU   s     r   rV   zMenuEntry.__cmp__  s1    ~~d//7795;M;M;U;U;WXXr   c                 H    t        | j                  j                               S rX   )r"   r   rT   r@   s    r   rY   zMenuEntry._key  s    ))11344r   c                 h    	 |j                         }| j                         |k  S # t        $ r Y w xY wrD   r[   rU   s     r   r]   zMenuEntry.__lt__  r^   r_   c                 6    | j                   t        |      k(  ryyr   )ri   rb   rU   s     r   rc   zMenuEntry.__eq__  s    U+r   c                     | j                   S rD   )ri   r@   s    r   __repr__zMenuEntry.__repr__"  s    !!!r   Nr   )r   r   r   r   r  r  r  rB   r	  r  r  r   r  r  rV   rY   r]   rc   r%  r   r   r   r   r     sS    .IKI<(&
E
"!!
GY5#"r   r   c                       e Zd ZdZd Zy)r   z!Just a dummy class for Separatorsc                      || _         d| _        y )NT)r2   r4   )rA   r}   s     r   rB   zSeparator.__init__(  s    	r   N)r   r   r   r   rB   r   r   r   r   r   &  s
    'r   r   c                       e Zd ZdZd Zd Zy)r   zClass for Inline Headersc                 .    || _         || _        || _        y rD   )r   r   r   )rA   r   generic_namecomments       r   rB   zHeader.__init__/  s    	'r   c                     | j                   S rD   rE   r@   s    r   rF   zHeader.__str__4  rG   r   N)r   r   r   r   rB   rF   r   r   r   r   r   -  s    
r   r   r   c                    t         j                  j                  |      }t         j                  j                  |       s t         j                  j	                  ||       } t         j                  j                  |       } t         j                  j                  |       sy|t        k(  r!t         j                  j                  |       r| S |t        k(  r!t         j                  j                  |       r| S yNF)ry   rt   dirnamer  rz   abspathexistsTYPE_DIRisdir	TYPE_FILEisfile)r   r   r   rt   s       r   _check_file_pathr6  ;  s    77??8$D77==T5)GGOOE"E77>>% xBGGMM%0yRWW^^E2r   c                    t        t              }t        j                  j                  du r|j                  d       |D ]F  }t        j                  j                  |d|       }t        j                  j                  |      sD|c S  y )NTr   r   )
listr   r   r   r  rx   ry   rt   rz   r5  )r   dirsdmenunames       r   _get_menu_file_pathr<  I  s^     D
zzt#77<<7H577>>(#O r   c                 L    t        | t              r| S | j                         dk(  S )Ntrue)r   boollower)r   s    r   _to_boolrA  S  s"    %;;=F""r   c                     i }| j                          | D cg c]  }||vs|j                  ||       } }| j                          | S c c}w rD   )rw   
setdefault)_list_setes      r   _deduperG  Z  sI    D	MMO,1CEqQd]T__Q"EEC	MMOL Ds
   	A	A	c                       e Zd ZddZd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y)XMLMenuBuilderc                     || _         y rD   )debug)rA   rK  s     r   rB   zXMLMenuBuilder.__init__d  s	    
r   Nc                    |r*t         j                  j                  |      st        |      }|s.t         j                  j                  dd      dz   }t        |      }|st        ddz        |j                  d      st        d|      	 t        j                  |      }t               | _        t               | _        t               | _        | j                  |j!                         |      }||_        ||_        | j'                  |       | j)                  |       | j+                  |       | j-                  |       |j/                          |S #  t        d|      xY w)	zLoad an applications.menu file.

        filename : str, optional
          The default is ``$XDG_CONFIG_DIRS/menus/${XDG_MENU_PREFIX}applications.menu``.
        XDG_MENU_PREFIXr,   applications.menuFile not foundz/etc/xdg/menus/%s.menuzNot a .menu fileNot a valid .menu file)ry   rt   r  r<  environgetr   endswithetreeparser   _merged_files_directory_dirsMenuEntryCachecache
parse_menugetrootr   r   handle_moves
post_parsegenerate_not_only_allocatedgenerate_only_allocatedr   )rA   r   	candidater   menus        r   rV  zXMLMenuBuilder.parseg  s1    BGGMM(3*84H

'8"=@SSI*95H/1Dy1PQQ  )18<<	C;;x(D
 !U"u#%
t||~x8	 $ 	((.$$T* 			-	C7BBs   E E c                 @    t               }| j                  |||       |S rD   )r*   
parse_node)rA   noder   rb  s       r   r[  zXMLMenuBuilder.parse_menu  s    vh-r   c                    t        |      }|D ]  }|j                  |j                  }}|r|j                         nd }|dk(  r$| j	                  ||      }|j                  |       Y|dk(  r|r| j                  |||       t|dk(  r| j                  ||       |dk(  r|r| j                  |||       |dk(  r| j                  ||       |dk(  r
|r||_
        |dk(  r|r|j                  j                  |       |dk(  rd	|_        |d
k(  r	d|_        |dk(  r	d	|_        |dk(  r	d|_        (|dk(  s|dk(  r,|j                  j                  | j!                  |             ^|dk(  rO|j"                  j%                  dd       dk(  r| j'                  d|||       |s| j'                  ||||       |dk(  r|r| j)                  ||||       |dk(  r| j+                  |||       |dk(  r,|j,                  j                  | j/                  |             |dk(  r|dkD  s&| j1                  |      |_        >|dk(  r|dkD  sJ| j1                  |      |_        b|dk(  r2|r0| j7                  ||j"                  j%                  dd      ||       |dk(  s| j9                  ||        y )Nr*   AppDirDefaultAppDirsDirectoryDirDefaultDirectoryDirsr   r-   r=   TNotOnlyUnallocatedFr#   
NotDeletedIncludeExclude	MergeFiler   r}   rN  MergeDirDefaultMergeDirsr   r:   rp   r7   	LegacyDirr  r,   KDELegacyDirs)rr   tagtextstripr[  rJ   parse_app_dirparse_default_app_dirparse_directory_dirparse_default_directory_dirr   r8   rI   r=   r#   r>   
parse_ruleattribrS  parse_merge_fileparse_merge_dirparse_default_merge_dirsr<   
parse_moveparse_layoutr:   r7   parse_legacy_dirparse_kde_legacy_dirs)	rA   re  r   r}   num_childrenchildrt  ru  rb  s	            r   rd  zXMLMenuBuilder.parse_node  s   4yE		5::C#'4::<TDf}uh7!!$'T""46:((**8V<&4((x@..006B4"#""))$/)))-&,,).&	!!%$!&	!SI%5##DOOE$:;#<<##FD1X=))*=uhPVW))$xH
"t$$T5(FC**--eXvF##DOOE$:;!#$($5$5e$<FM'!#+/+<+<U+CF(#%%dELL,<,<Xr,JHV\]'**8V<a r   c                 p   t        t        |j                  j                  dd            t        |j                  j                  dd            t	        |j                  j                  dd            t        |j                  j                  dd            t        |j                  j                  dd            	      }g }|D ]g  }|j
                  |j                  }}|r|j                         nd }|d
k(  r|r|j                  d
|t        |j                  j                  dd            t        |j                  j                  dd            t	        |j                  j                  dd            t        |j                  j                  dd            t        |j                  j                  dd            g       |dk(  r|j                  dg       |dk(  r|r|j                  d|g       4|dk(  s;|j                  d|j                  j                  dd      g       j ||_	        |S )Nr   Fr   r   r
   r   Tr   )r   r   r   r   r   r   r   r0   r   r   r   )
r:   rA  r|  rS  intrt  ru  rv  rI   r   )rA   re  layoutr   r  rt  ru  s          r   r  zXMLMenuBuilder.parse_layout  s   e DEDKKOOHe<=T[[__^Q?@"4;;???D#IJ!$++//.%"HI
 E		5::C#'4::<TDj TU\\--lEBCU\\--h>?((;<U\\--otDEU\\--neDE  #k]+
"tj$/0LL$$VU3 % , r   c                     d\  }}|D ]C  }|j                   |j                  }}|r|j                         nd }|dk(  r|r|}9|dk(  s?|sB|}E t        ||      S )Nr   r   r   )rt  ru  rv  r   )rA   re  r   r   r  rt  ru  s          r   r  zXMLMenuBuilder.parse_move  s_    SE		5::C#'4::<TDe|$  C~r   c                 L   |j                   dk(  rt        j                  nt        j                  }t	        j
                  dd      }| j                  |t	        j                               }|r||_        nt        d      |_        t	        j                  |       t        ||      S )Nrm  rp   r   )r   r   False)rt  r   r   r   r   r   parse_bool_opOrr   r   r   )rA   re  r   r   exprs        r   r{  zXMLMenuBuilder.parse_rule  sy    $(HH	$9t  t?P?P~~Q15!!$1DI"7+DI!!$'D$r   c                     g }|D ]'  }| j                  |      }|s|j                  |       ) t        |      }|dkD  rt        j                  ||      S |dk(  r|d   S y )Nrp   r   )parse_rule_noderI   rr   r   BoolOp)rA   re  operatorvaluesr  rN   
num_valuess          r   r  zXMLMenuBuilder.parse_bool_op  sg    E''.Dd#  [
>::h//1_!9r   c                    |j                   }|dk(  r$| j                  |t        j                               S |dk(  r$| j                  |t        j                               S |dk(  rP| j                  |t        j                               }|r(t        j
                  t        j                         |      S d S |dk(  rt        d      S |dk(  r|j                  }t        j                  t        j                  |      t        j                         gt        j                  t        j                  dt        j                               d	t        j                         
      g      S |dk(  r|j                  }t        j                  t        j                  |      t        j                         gt        j                  t        j                  dt        j                               dt        j                         
      g      S y )Nr  AndNotAllTrueCategoryrm   r   r  r   r   r0   ri   )rt  r  r   r  r  UnaryOpr  r   ru  r   r   Inr   r   r   r   )rA   re  rt  r  categoryr   s         r   r  zXMLMenuBuilder.parse_rule_node  su   hh$;%%dCFFH55E\%%dCGGI66E\%%dCFFH5D373;;swwy$/ATAE\f%%JyyH;;WWX&VVXJ ]]((ksxxzB%
   JyyH;;WWX&VVXJ ]]((ksxxzB(
   r   c                 b    t        ||t              }|r|j                  j                  |       y y rD   )r6  r2  r6   rI   rA   r   r   r}   s       r   rw  zXMLMenuBuilder.parse_app_dir8  s*     (;NN!!%( r   c                     t        t              D ]3  }| j                  t        j                  j                  |d      ||       5 y )Nr  )reversedr   rw  ry   rt   rz   rA   r   r}   r:  s       r   rx  z$XMLMenuBuilder.parse_default_app_dir=  s2    -(Arww||A~>&Q )r   c                 b    t        ||t              }|r|j                  j                  |       y y rD   )r6  r2  r9   rI   r  s       r   ry  z"XMLMenuBuilder.parse_directory_dirA  s,     (;  ''. r   c                     t        t              D ]3  }| j                  t        j                  j                  |d      ||       5 y )Nr  )r  r   ry  ry   rt   rz   r  s       r   rz  z*XMLMenuBuilder.parse_default_directory_dirF  s4    -(A$$RWW\\!5J%KXW]^ )r   c                    |j                   j                  dd       dk(  rt        D ]  }|j                  |d      j	                  d      }||k7  s*t        D ]x  }||k(  r	t
        j                  j                  t
        j                  j                  ||            sG| j                  t
        j                  j                  ||      ||          y t        ||t              }|r| j                  |||       y y )Nr   r}   r,   ro   )r|  rS  r   r  rv  ry   rt   r5  rz   
merge_filer6  r4  )rA   r   r  r   r}   r:  rel_fileps           r   r}  zXMLMenuBuilder.parse_merge_fileL  s    <<FD)X5$#++Ar288=x',6$77>>"'',,q(*CD OOBGGLLH,EufU! - % %UHi@Euf5 r   c                    t        ||t              }|r^t        j                  |      D ]E  }	 |j	                  d      r1| j                  t        j                  j                  ||      ||       G y y # t        $ r Y Uw xY w)NrP  )	r6  r2  ry   listdirrT  r  rt   rz   UnicodeDecodeError)rA   r   r  r   r}   items         r   r~  zXMLMenuBuilder.parse_merge_dir\  sp     (;

5)}}W-UD(A5&Q * 
 * s   AA33	A?>A?c           	         t         j                  j                  t         j                  j                  |            d   }t	        t
              D ]8  }| j                  t         j                  j                  |d|dz         |||       : y )Nr   r   z-merged)ry   rt   splitextbasenamer  r   r~  rz   )rA   r  r   r}   r  r:  s         r   r  z'XMLMenuBuilder.parse_default_merge_dirsf  sf    77##BGG$4$4X$>?B/*A  a(Y:N!OQVX`bhi +r   c                 |   || j                   v r| j                  rt        d|      y | j                   j                  |       	 t	        j
                  |      }|j                         }| j                  |||       y # t        $ r | j                  rt        d|      Y y  | j                  rt        d|      Y y xY w)Nz Infinite MergeFile loop detectedrO  rQ  )	rW  rK  r   r   rU  rV  IOErrorr\  rd  )rA   r   r  r}   r   roots         r   r  zXMLMenuBuilder.merge_filek  s    t)))zz"#ExPPx(	;;x(D ||~h/  	zz"#3X>>	zz"#;XFFs   A= =!B; B;c                 <    | j                  ||||      }|r||z  }y y rD   )merge_legacy_dir)rA   r  r  r   r}   ms         r   r  zXMLMenuBuilder.parse_legacy_dir  s)    !!$&AaKF r   c           	         t        ||t              }|r|| j                  vr| j                  j                  |       t	               }|j
                  j                  |       |j                  j                  |       t        j                  j                  |      |_        d|_        t        j                  |      D ]  }	 |dk(  r|j                  j                  |       n~t        j                  j                  t        j                  j!                  ||            rA|j#                  | j%                  t        j                  j!                  ||      |||              | j(                  j+                  |g|d       | j(                  j-                  |gd      }|D ]  }|j.                  }	t1        |	      dk(  rIt2        j5                  t2        j6                  |j8                        }
|j:                  j                  |
       ||j
                  vsu|	j                  d       |	|_         |S y y # t&        $ r Y w xY w)NTz
.directoryFr   Legacy)r6  r2  rX  r   r*   r6   rI   r9   ry   rt   r  r   r3   r  r8   r3  rz   rJ   r  r  rZ  add_menu_entriesget_menu_entriesr  rr   r   r   r   ri   r>   )rA   r  r  r   r}   r  r  r   rm   
categoriesrs              r   r  zXMLMenuBuilder.merge_legacy_dir  s   h9D 4 44  $$T*AIIT"OO""4(WW%%d+AFAJ

4(|+,,T2rww||D$'?@T%:%:GGLLt4"$"	&  ) JJ''=**55tfeDK(	&11
z?a'))$*;*;Y=T=TUAGGNN1%v~~-%%h/+5I( ) HE 54& * s   BH44	I Ic                 0   	 t        j                  g dt         j                  d      }|j                         d   j	                         }	 |d   j                  d      D ]  }| j                  |d||        y # t
        $ r Y y w xY w# t        $ r Y y w xY w)N)z
kde-configz--pathappsT)stdoutuniversal_newlinesr   :kde)	
subprocessPopenPIPEcommunicate
splitlinesOSErrorrq   r  
IndexError)rA   r   r}   procoutputr  s         r   r  z$XMLMenuBuilder.parse_kde_legacy_dirs  s    		##0!#'D
 %%'*557F	q	,%%dE8VD -	  		  		s$   A	A: -B	 :	BB		BBc                 &   |j                   d|_         |j                  d|_        |j                  r|j                  s|j                  r|j                  |_        n|j                  r;|j                  dkD  r|j
                  j                  |_        ntt               |_        nd|j                  dkD  r7|j
                  j                  |_        |j
                  j                  |_        nt               |_        t               |_        |j                  dkD  rP|j
                  j                  |j                  z   |_        |j
                  j                  |j                  z   |_        t        |j                        |_	        t        |j                        |_        t        |j                        |_        |j                  D ]  }| j                  |        |j                  j                          |j                  j                          |j                  j                          |j                  D ]  }|j                  D ]  }t        j                  j                  t        j                  j!                  ||            sAt#        ||      }|j$                  s||_        a|j'                         t"        j(                  k(  s|j$                  j'                         t"        j*                  k(  s||j$                  _         |j$                  s y  y )NFr   )r#   r=   r:   r7   r1   r2   r6   r9   rG  r8   r?   r^  rw   ry   rt   r5  rz   r   r-   r  r  r  r   )rA   rb  rP   rM   rL   rm   s         r   r^  zXMLMenuBuilder.post_parse  s0   << DL'#(D  {{$"4"4!!"00::>)-)B)BD&)/D&::>"&++";";DK)-)B)BD&"((DK)/D& ::>;;..=DL!%!:!:T=O=O!OD #4#3#34$T%7%78t||, }}GOOG$ % 	  """$ ))I))77>>"'',,sI">? ))S 9I>>)2"**,	0E0EE>>113y7J7JJ6?DNN3 * ~~ *r   c                    |j                   D ]  }| j                  |        |j                  du r| j                  j	                  |j
                         g }|j                  D ]7  }|j                  | j                  j                  |j
                        d      }9 |D ]U  }|j                  du s|j                  j                  |       d|_	        d|_        |j                  j                  |       W y y )NFrp   T)r?   r_  r=   rZ  r  r6   r>   r   r  r   r  rI   r   r;   rA   rb  rP   r   rN   rm   s         r   r_  z*XMLMenuBuilder.generate_not_only_allocated  s    }}G,,W5 % 5(JJ''5K

"jj)D)DT\\)RTUV # )	==D(%%,,T2$)IM*.I'$$++I6 ) )r   c                    |j                   D ]  }| j                  |        |j                  du r| j                  j	                  |j
                         g }|j                  D ]7  }|j                  | j                  j                  |j
                        d      }9 |D ]G  }|j                  du s|j                  j                  |       |j                  j                  |       I y y )NTr   )r?   r`  r=   rZ  r  r6   r>   r   r  r   r  rI   r;   r  s         r   r`  z&XMLMenuBuilder.generate_only_allocated  s    }}G((1 % 4'JJ''5K

"jj)D)DT\\)RTUV #(	==D(%%,,T2 $$++I6 ) (r   c                 v   |j                   D ]  }| j                  |        |j                  D ]  }|j                  |j                        }|s"|j                  |j
                        }|j
                  j                  d      }d }t        |      dkD  rv|s|}|j                  |d         }|s:t               }|d   |_	        t        |      dkD  rd|_
        |j                  |       |}|j                  d       t        |      dkD  rv|z  }|j                  j                   j                  |       
 y )Nro   r   rp   T)r?   r]  r<   rs   r   r   rq   rr   r*   r   r3   rJ   rx   r2   r   )	rA   rb  rP   rO   move_from_menumove_to_menur   	oldparentr   s	            r   r]  zXMLMenuBuilder.handle_moves  s   }}Gg& % JJD!\\$((3N#||DHH5s+ 	%j1n$$(	'//a9G""&&',Qxu:>/3G,!,,W5 'IIIaL %j1n >)%%..55nE- r   r   rD   )r   r   r   rB   rV  r[  rd  r  r  r{  r  r  rw  rx  ry  rz  r}  r~  r  r  r  r  r  r^  r_  r`  r]  r   r   r   rI  rI  b  s    +Z
2=h D		  H)
R/
_6 j
04
$L"6r7"7 Fr   rI  c                   ,    e Zd ZdZd ZddZd ZddZy)	rY  zClass to cache Desktop Entriesc                 >    i | _         g | j                   d<   i | _        y )Nlegacy)cacheEntriesrZ  r@   s    r   rB   zMenuEntryCache.__init__:  s!    &((#
r   c                 v    |D ]4  }|| j                   vsg | j                   |<   | j                  |d||       6 y )Nr,   )r  _MenuEntryCache__addFiles)rA   r9  r  r  r  s        r   r  zMenuEntryCache.add_menu_entries?  s<    D4,,,*,!!$'b&&9 r   c                 v   t        j                  t         j                  j                  ||            D ]  }|j	                  d      rl	 t        t         j                  j                  ||      ||      }| j                  |   j                  |       |sa| j                  d   j                  |       t         j                  j                  t         j                  j                  |||            s|r| j                  |t         j                  j                  ||      ||        y # t        $ r Y w xY w)Nz.desktopr  )ry   r  rt   rz   rT  r   r   r  rI   r3  r  )rA   r  subdirr  r  r  rm   s          r   
__addFileszMenuEntryCache.__addFilesE  s    JJrww||D&9:D}}Z( )"'',,vt*DdF SI !!$'..y9%%h/66yArww||D&$?@bggll64&@&&Q ; $ s   	+D++	D87D8c                 V   g }t               }|d d  }|r|j                  d       dj                  |      }	 | j                  |   S # t        $ r Y nw xY w|D ]  }| j
                  |   D ]  }	 |j                  |vr-|j                  |j                         |j                  |       n_|j                         t        j                  k(  r>|j                  |      }	||	   }
|
j                         t        j                  k(  r||
_        # t        $ r Y w xY w  || j                  |<   |S )Nr  r,   )r   rI   rz   rZ  KeyErrorr  ri   r   r  r   r  indexr  r   r  )rA   r9  r  entriesidsappdirskeyr  rm   idxrf   s              r   r  zMenuEntryCache.get_menu_entriesS  s   eq'NN8$ggg	::c?" 		D!..t4	 ..c9	 7 78y1"**,	0E0EE%mmI6 ' ==?i.A.AA-6EN)  5  "

3s$   A 	AA-BD	DDN)r,   F)T)r   r   r   r   rB   r  r  r  r   r   r   rY  rY  8  s    $
:Rr   rY  c                 6    t        |      j                  |       S )zYHelper function.
    Equivalent to calling xdg.Menu.XMLMenuBuilder().parse(filename)
    )rI  rV  )r   rK  s     r   rV  rV  r  s     % &&x00r   r.  )1r   ry   r   r  r   r   xml.etree.cElementTreerU  cElementTreeImportErrorxml.etree.ElementTreeElementTreexdg.BaseDirectoryr   r   xdg.DesktopEntryr   xdg.Exceptionsr   xdg.utilr   
xdg.Localer   
xdg.Configr   r"   r   r   r   r   r   r   r*   r   r:   r   r   r   r   r2  r4  r6  r<  rA  rG  objectrI  rY  rV  r   r   r   <module>r     s
  & 
   
 
*** = ) '   1 
	
l) l)^	( ( 0, ,^_" _"D    )#SFV SFl7 7t1o"  *))*s   	C CC