o àÕþ_´šã@sŠdZddlZddlZddlZddlZddlZz ddlmmZWne y3ddl mm ZYnwddl m Z mZddlmZddlmZddlmZddlZddlZdd„Zd d „Zd Zd Zd ZdZdZdZGdd„dƒZ Gdd„dƒZ!Gdd„dƒZ"Gdd„dƒZ#Gdd„dƒZ$Gdd„dƒZ%Gdd„dƒZ&d\Z'Z(d d!„Z)d"d#„Z*d$d%„Z+d&d'„Z,Gd(d)„d)e-ƒZ.Gd*d+„d+ƒZ/d/d-d.„Z0dS)0a· 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)ÚPY3cCsDtjdkrt |¡}tjdkrt |¡St |¡Stj|t ¡dS)N)éé)ré©ÚidÚctx)ÚsysÚ version_infoÚastÚ literal_evalÚConstantÚ NameConstantÚNameÚLoad)Úname©rú*/usr/lib/python3/dist-packages/xdg/Menu.pyÚ _ast_const's     rcCs"ts t|tƒr | d¡}t |¡S)zgWrapper around locale.strxfrm that accepts unicode strings on Python 2. See Python bug #2481. zutf-8)rÚ isinstanceÚunicodeÚencodeÚlocaleÚstrxfrm)ÚsrrrÚ_strxfrm2s  rÚDeletedÚ NoDisplayÚHiddenÚEmptyÚ NotShowInÚNoExecc@sªeZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z d(dd„Z d(dd„Z dd„Z d)dd„Zdd„Zdd„Zdd„Zdd „Zd!d"„Z d#d$„Zd%d&„Zd'S)*ÚMenuz^Menu containing sub menus under menu.Entries Contains both Menu and MenuEntry items. cCs‚d|_d|_g|_d|_d|_d|_d|_d|_d|_d|_ g|_ d|_ d|_ g|_ g|_d|_g|_g|_d|_g|_g|_dS)NÚrFT)rÚ DirectoryÚEntriesÚDocÚFilenameÚDepthÚParentÚNotInXmlÚShowÚVisibleÚAppDirsÚ DefaultLayoutr Ú DirectoriesÚ DirectoryDirsÚLayoutÚ MenuEntriesÚMovesÚOnlyUnallocatedÚRulesÚSubmenus©ÚselfrrrÚ__init__Is* z Menu.__init__cCó|jS©N©rr;rrrÚ__str__eóz Menu.__str__cCsÒ|jD]}|j |¡q|jD]}|j |¡q|jD]}|j |¡q|jdur-|j|_|jdur6|j|_|jr=|j|_|jrD|j|_|jD]}|j |¡qG|j D]}|j  |¡qS|j D]}|  |¡q_|Sr?) r1Úappendr4r3r r8r5r2r9r7r:Ú addSubmenu)r<ÚotherÚdirÚ directoryÚruleÚmoveÚsubmenurrrÚ__add__hs*         z Menu.__add__cCst | ¡| ¡¡Sr?)rÚstrcollÚgetName©r<rErrrÚ__cmp__Šsz Menu.__cmp__cCs t| ¡ƒS©z&Key function for locale-aware sorting.)rrMr;rrrÚ_keys z Menu._keycCó,z| ¡}Wn tyYnw| ¡|kSr?©rQÚAttributeErrorrNrrrÚ__lt__‘ó   ÿ z Menu.__lt__cCs2z|jt|ƒkWSty|jt|ƒkYSwr?)rrÚ NameErrorÚstrrNrrrÚ__eq__˜s  ÿz Menu.__eq__Fccs.|jD]}|r |Vq|jdur|VqdS)z4Interator for a list of Entries visible to the user.TN)r)r/)r<Ú show_hiddenÚentryrrrÚ getEntriesŸs€  €üzMenu.getEntriescCsB|jD] }|j|kr|Sq|r|jD] }| ||¡qdSdS)z4Searches for a MenuEntry with a given DesktopFileID.N)r6Ú DesktopFileIDr:Ú getMenuEntry)r<Ú desktopfileidÚdeepÚ menuentryrJrrrr^«s  ÿ þzMenu.getMenuEntrycCsP| dd¡}|jD]}|j|dkr%t|ƒdkr!| |d¡S|Sq dS)z&Searches for a Menu with a given path.ú/érN)Úsplitr:rÚlenÚgetMenu)r<ÚpathÚarrayrJrrrrf´s   üÿz Menu.getMenucCsv|}g} |r| |j¡n| | ¡¡|jdkr|j}nnq| ¡d}|s-| d¡|D] }tj  ||¡}q/|S)z/Returns this menu's path in the menu structure.rcrr') rCrrMr,r-ÚreverseÚpopÚosrgÚjoin)r<ÚorgÚtoplevelÚparentÚnamesrgrrrrÚgetPath¾s" ø  z Menu.getPathcCs(z|jj ¡WSty|jYSw)z"Returns the menu's localised name.)r(rrMrTrr;rrrrMÓs   ÿz Menu.getNamecCó$z|jj ¡WStyYdSw)z Returns the menu's generic name.r')r(rÚgetGenericNamerTr;rrrrsÚó  ÿzMenu.getGenericNamecCrr)z Returns the menu's comment text.r')r(rÚ getCommentrTr;rrrruártzMenu.getCommentcCrr)z0Returns the menu's icon, filename or simple namer')r(rÚgetIconrTr;rrrrvèrtz Menu.getIconcCs2g|_d|_|jD]}| ¡q tƒ}tƒ}|jjD]}|ddkr*| |d¡q|ddkr7| |d¡q|jjD]°}|ddkrat|ƒ}t |jƒdkrZt |jdtƒrZd|_ |j  |¡q<|ddkrw|  |d¡}|rv|j  |¡q<|ddkr—| |d¡}|r–|jjr| |¡q<|j  |¡q<|ddkrì|dd ks©|dd krÀ|j ¡|jD] }|j|vr¾|j  |¡q±q<|dd ksÌ|dd krì|j ¡|jD]}|j|vrë|jjrå| |¡qÔ|j  |¡qÔq<|jD]Æ}d |_ |jd7_t |tƒr>|jd urt|_ |jd8_qðt |jtƒr=|jj ¡r,t|_ |jd8_qð|jj ¡r=t|_ |jd8_qðt |tƒr©|j ¡rUt|_ |jd8_qð|j ¡rft|_ |jd8_qð|j ¡r}|j ¡s}t |_ |jd8_qðt!j"j#r¨|j $¡gkr”t!j"j#|j $¡vsžt!j"j#|j %¡vr¨t&|_ |jd8_qðt |tƒr¶|jd8_qðt |jƒdkrÎt |jdtƒrÎd|jd_ t |jƒdkråt |jdtƒråd|jd_ |jdd…D]*}t |tƒr|jj's|jdkrt(|_ |jd8_|j)d ur|j *|¡qìdS) Nrr+rcÚMenunameÚ SeparatoréÿÿÿÿFÚMergeÚfilesÚallÚmenusT)+r)r0r:ÚsortÚsetr5ÚorderÚaddrxrerr/rCr^rfÚinlineÚ merge_inliner6r]rr&r ÚDELETEDr(Ú MenuEntryrÚ getNoDisplayÚ NO_DISPLAYÚ getHiddenÚHIDDENÚ getTryExecÚ findTryExecÚNO_EXECÚxdgÚConfigÚ windowmanagerÚ getOnlyShowInÚ getNotShowInÚ NOT_SHOW_INÚ show_emptyÚEMPTYr.Úremove)r<rJÚ _submenusÚ_entriesr€Ú separatorrar[rrrr~ïs¾     €    €   €     €þ     €   €    € €  "  €ûz Menu.sortcCsD|jD] }||kr||7}dSq|j |¡||_|jd|_dS)Nrc)r:rCr-r,)r<ÚnewmenurJrrrrDTs þ zMenu.addSubmenucCsèt|jƒdkr9|jjr9|jd}|jjd| ¡dd|jjd| ¡dd|jjd| ¡dd|j  |¡dSt|jƒ|jj ksH|jj dkrl|jj r^t | ¡| ¡| ¡ƒ}|j  |¡|jD]}|j  |¡qadS|j  |¡dS) z}Appends a submenu's entries to this menu See the section of the spec about the "inline" attribute rcrrT)rÚ GenericNameÚCommentN) rer)r5Ú inline_aliasrrrMrsrurCÚ inline_limitÚ inline_headerÚHeader)r<rJraÚheaderr[rrrrƒ_s   ÿzMenu.merge_inlineN©F)FF)Ú__name__Ú __module__Ú __qualname__Ú__doc__r=rArKrOrQrUrYr\r^rfrqrMrsrurvr~rDrƒrrrrr&Ds,"   d r&c@s"eZdZdZddd„Zdd„ZdS) ÚMovezA move operationr'cCs||_||_dSr?)ÚOldÚNew)r<ÚoldÚnewrrrr=uó z Move.__init__cCst|j|jƒSr?)Úcmpr§rNrrrrOysz Move.__cmp__N©r'r')r¢r£r¤r¥r=rOrrrrr¦ss  r¦c@s8eZdZdZ  d dd„Zedd„ƒZejd d„ƒZd S) r5zMenu Layout classFrTcCs:||_||_||_||_||_g|_ddgddgg|_dS)Nrzr}r{)r“r‚rržrœÚ_orderÚ_default_order)r<r“r‚rržrœrrrr=s þzLayout.__init__cCs|jr|jS|jSr?)r®r¯r;rrrr€Œóz Layout.ordercCó ||_dSr?)r®)r<r€rrrr€s N)FFrTF)r¢r£r¤r¥r=Úpropertyr€Úsetterrrrrr5}s ÿ r5c@s<eZdZdZd\ZZedd„ƒZdd„Zdd„Z d d „Z d S) ÚRulezInclude / Exclude Rules Class©rrcc Cs`tjtjt |¡t ¡gtjtjdt ¡ddt ¡dgdddd}t |¡t ||ƒ}|S) Nrar r]©ÚvalueÚattrr ©ÚleftÚopsÚ comparatorsrcr)ÚbodyÚlinenoÚ col_offset) rÚ ExpressionÚCompareÚStrÚEqÚ AttributerrÚfix_missing_locationsr´)ÚclsÚtypeÚfilenameÚtreerHrrrÚ fromFilenamešsýý ö zRule.fromFilenamecCs ||_||_t|jddƒ|_dS)NzÚeval)ÚTypeÚ expressionÚcompileÚcode)r<rÇrÍrrrr=¬sz Rule.__init__cCs t |j¡Sr?)rÚdumprÍr;rrrrA³s z Rule.__str__cCsV|D]&}|dkr|jdus|jdurqt|jƒr(|jtjur%d|_d|_qd|_q|S)NéTF)ÚMatchedIncludeÚ AllocatedrËrÏrÌr´Ú TYPE_INCLUDEÚAdd)r<Ú menuentriesÚrunrarrrÚapply¶s   €z Rule.applyN) r¢r£r¤r¥rÔÚ TYPE_EXCLUDEÚ classmethodrÊr=rArØrrrrr´•s  r´c@s€eZdZdZdZdZdZddd„Zdd „Zd d „Z d d „Z ddd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zdd„ZdS) r…z(Wrapper for 'Menu Style' Desktop EntriesÚUserÚSystemÚBothr'cCsVttj ||¡ƒ|_| |||¡d|_d|_g|_d|_d|_ d|_ |j  ¡|_ dS©NTF) rrkrgrlÚ setAttributesr/ÚOriginalÚParentsrÓrÕrÒÚ getCategoriesÚ Categories©r<rÈrFÚprefixrrrr=ËszMenuEntry.__init__cCs|jjr |j ¡dSdS)z&Save any changes to the desktop entry.N)rÚtaintedÚwriter;rrrÚsaveßsÿzMenuEntry.savecCs|jj |jd¡S)z7Return the directory containing the desktop entry file.r')rrÈÚreplacer+r;rrrÚgetDirär°zMenuEntry.getDircCs6tjjs|jr |jStd|jjvr|jS|j S|jS)z.Return the type of MenuEntry, System/User/Bothr) rrŽÚ root_moderàÚ TYPE_BOTHrrrÈÚ TYPE_USERÚ TYPE_SYSTEMr;rrrÚgetTypeèszMenuEntry.getTypecCsD||_||_tj ||¡ dd¡|_tj |jj ¡s |  ¡dSdS)Nrbú-) r+ÚPrefixrkrgrlrér]ÚisabsrrÈÚ_MenuEntry__setFilenamerärrrrßôs  ÿzMenuEntry.setAttributescCs4| ¡|jkrt|j| ¡|jƒ|_| ¡dSdSr?)rïrîr…r+rêrñràrór;rrrÚupdateAttributesüs þzMenuEntry.updateAttributescCs^tjjs td}ntd}|j ¡dkrtj |d¡}ntj |d¡}tj ||j ¡|j_ dS)NrrcÚ ApplicationÚ applicationsúdesktop-directories) rrŽrërrrïrkrgrlr+rÈ)r<rgÚdir_rrrÚ __setFilenames zMenuEntry.__setFilenamecCst |j ¡|j ¡¡Sr?)rrLrrMrNrrrrOszMenuEntry.__cmp__cCst|j ¡ƒSrP)rrrMr;rrrrQszMenuEntry._keycCrRr?rSrNrrrrUrVzMenuEntry.__lt__cCs|jt|ƒkr dSdSrÞ)r]rXrNrrrrYszMenuEntry.__eq__cCr>r?)r]r;rrrÚ__repr__"rBzMenuEntry.__repr__Nr­)r¢r£r¤r¥rírîrìr=rèrêrïrßrôrórOrQrUrYrúrrrrr…Äs"    r…c@seZdZdZdd„ZdS)rxz!Just a dummy class for SeparatorscCs||_d|_dS)NT)r-r/)r<rorrrr=(r«zSeparator.__init__N)r¢r£r¤r¥r=rrrrrx&s rxc@s eZdZdZdd„Zdd„ZdS)rŸzClass for Inline HeaderscCs||_||_||_dSr?)rršr›)r<rÚ generic_nameÚcommentrrrr=/s zHeader.__init__cCr>r?r@r;rrrrA4rBzHeader.__str__N)r¢r£r¤r¥r=rArrrrrŸ-s rŸrµcCsvtj |¡}tj |¡stj ||¡}tj |¡}tj |¡s!dS|tkr-tj |¡r-|S|t kr9tj  |¡r9|SdS©NF) rkrgÚdirnameròrlÚabspathÚexistsÚTYPE_DIRÚisdirÚ TYPE_FILEÚisfile)r·rÈrÇrgrrrÚ_check_file_path;s    rcCsPttƒ}tjjdur| d¡|D]}tj |d|¡}tj  |¡r%|SqdS)NTrr}) ÚlistrrrŽrërjrkrgrlr)rÈÚdirsÚdÚmenunamerrrÚ_get_menu_file_pathIs   ÿþr cCst|tƒr|S| ¡dkS)NÚtrue)rÚboolÚlower)r·rrrÚ_to_boolSs  rcs*i‰| ¡‡fdd„|Dƒ}| ¡|S)Ncs g|] }|ˆvrˆ ||¡‘qSr)Ú setdefault)Ú.0Úe©Ú_setrrÚ ]s z_dedupe..)ri)Ú_listrrrÚ_dedupeZs rc@sÒeZdZd3dd„Zd4dd„Zdd„Zd4d d „Zd d „Zd d„Zdd„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd „Zd!d"„Zd#d$„Zd%d&„Zd'd(„Zd)d*„Zd+d,„Zd-d.„Zd/d0„Zd1d2„ZdS)5ÚXMLMenuBuilderFcCr±r?)Údebug)r<rrrrr=ds zXMLMenuBuilder.__init__NcCs|r tj |¡s t|ƒ}|s*tj dd¡d}t|ƒ}|s*tj dd¡d}t|ƒ}|s3tdd|ƒ‚| d¡s=td|ƒ‚zt  |¡}Wntd |ƒ‚t ƒ|_ t ƒ|_ t ƒ|_| | ¡|¡}||_||_| |¡| |¡| |¡| |¡| ¡|S) z£Load an applications.menu file. filename : str, optional The default is ``$XDG_CONFIG_DIRS/menus/${XDG_MENU_PREFIX}applications.menu``. ÚXDG_MENU_PREFIXr'úapplications.menuzdebian-menu.menuúFile not foundz/etc/xdg/menus/%sú.menuzNot a .menu fileúNot a valid .menu file)rkrgrò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~)r<rÈÚ candidaterÉÚmenurrrr"gs< ÿ       zXMLMenuBuilder.parsecCstƒ}| |||¡|Sr?)r&Ú parse_node)r<ÚnoderÈr.rrrr'szXMLMenuBuilder.parse_menuc Csbt|ƒ}|D]'}|j|j}}|r| ¡nd}|dkr(| ||¡}| |¡q|dkr6|r6| |||¡q|dkrA| ||¡q|dkrO|rO| |||¡q|dkrZ|  ||¡q|dkrd|rd||_ q|dkrq|rq|j   |¡q|dkryd |_ q|d krd |_ q|d kr‰d |_q|d kr‘d |_q|dks™|dkr£|j  | |¡¡q|dkrÄ|j dd¡dkr¹| d|||¡q|rÃ| ||||¡q|dkrÓ|rÓ| ||||¡q|dkrß| |||¡q|dkrí|j  | |¡¡q|dkrü|dkrû| |¡|_q|dkr |dkr | |¡|_q|dkr#|r#| ||j dd¡||¡q|dkr.| ||¡qdS)Nr&ÚAppDirÚDefaultAppDirsÚ DirectoryDirÚDefaultDirectoryDirsrr(r8TÚNotOnlyUnallocatedFr Ú NotDeletedÚIncludeÚExcludeÚ MergeFilerÇrorÚMergeDirÚDefaultMergeDirsr¦r5rcr2Ú LegacyDirrår'Ú KDELegacyDirs)reÚtagÚtextÚstripr'rDÚ parse_app_dirÚparse_default_app_dirÚparse_directory_dirÚparse_default_directory_dirrr3rCr8r r9Ú parse_ruleÚattribrÚparse_merge_fileÚparse_merge_dirÚparse_default_merge_dirsr7Ú parse_moveÚ parse_layoutr5r2Úparse_legacy_dirÚparse_kde_legacy_dirs) r<r0rÈroÚ num_childrenÚchildr>r?r.rrrr/¢sn       €  €   €  €ÐzXMLMenuBuilder.parse_nodecCsLtt|j dd¡ƒt|j dd¡ƒt|j dd¡ƒt|j dd¡ƒt|j dd¡ƒd }g}|D]p}|j|j}}|r?| ¡nd}|d krw|rw| d |t|j dd¡ƒt|j dd¡ƒt|j dd¡ƒt|j dd¡ƒt|j dd¡ƒg¡q0|d kr‚| d g¡q0|d kr|r| d |g¡q0|d kr | d |j dd¡g¡q0||_ |S)Nr“Fr‚rrržTrœ)r“r‚rržrœrwrxr+rzrÇr|) r5rrFrÚintr>r?r@rCr€)r<r0Úlayoutr€rOr>r?rrrrKÖsBû ù   þ€zXMLMenuBuilder.parse_layoutcCs\d\}}|D]"}|j|j}}|r| ¡nd}|dkr |r |}q|dkr(|r(|}qt||ƒS)Nr­r§r¨)r>r?r@r¦)r<r0r©rªrOr>r?rrrrJøs  € zXMLMenuBuilder.parse_movecCs^|jdkrtjntj}tjddd}| |t ¡¡}|r ||_nt dƒ|_t  |¡t||ƒS)Nr7rcr)r¾r¿ÚFalse) r>r´rÔrÙrrÀÚ parse_bool_opÚOrr½rrÅ)r<r0rÇrÉÚexprrrrrEs   zXMLMenuBuilder.parse_rulecCsVg}|D]}| |¡}|r| |¡qt|ƒ}|dkr!t ||¡S|dkr)|dSdS)Nrcr)Úparse_rule_noderCrerÚBoolOp)r<r0ÚoperatorÚvaluesrOrHÚ num_valuesrrrrSs  € zXMLMenuBuilder.parse_bool_opcCs|j}|dkr| |t ¡¡S|dkr| |t ¡¡S|dkr3| |t ¡¡}|r1t t ¡|¡SdS|dkr;tdƒS|dkr`|j}tj t  |¡t  ¡gtj tj dt ¡dd t ¡d gd S|d kr…|j}tj t  |¡t ¡gtj tj dt ¡dd t ¡d gd SdS)NrTÚAndÚNotÚAllÚTrueÚCategoryrar rãr¶r¹r+r])r>rSrrTr[ÚUnaryOpr\rr?rÁrÂÚInrÄrrrÃ)r<r0r>rUÚcategoryrÈrrrrVsBýý ýýþzXMLMenuBuilder.parse_rule_nodecCó$t||tƒ}|r|j |¡dSdSr?)rrr1rC©r<r·rÈrorrrrAAó ÿzXMLMenuBuilder.parse_app_dircCó*ttƒD]}| tj |d¡||¡qdS)Nrö)ÚreversedrrArkrgrl©r<rÈrorrrrrBFó ÿz$XMLMenuBuilder.parse_default_app_dircCrcr?)rrr4rCrdrrrrCJrez"XMLMenuBuilder.parse_directory_dircCrf)Nr÷)rgrrCrkrgrlrhrrrrDOriz*XMLMenuBuilder.parse_default_directory_dircCs¦|j dd¡dkr@tD]2}| |d¡ d¡}||kr=tD] }||kr#qtj tj ||¡¡r<|  tj ||¡||¡nqq dSt ||t ƒ}|rQ|  |||¡dSdS)NrÇror'rb) rFrrrér@rkrgrrlÚ merge_filerr)r<r·rOrÈrorÚrel_fileÚprrrrGUs"þ€ú ÿzXMLMenuBuilder.parse_merge_filec Cs`t||tƒ}|r,t |¡D] }z| d¡r!| tj ||¡||¡Wq ty+Yq wdSdS)Nr) rrrkÚlistdirr rjrgrlÚUnicodeDecodeError)r<r·rOrÈroÚitemrrrrHes  € ÿûzXMLMenuBuilder.parse_merge_dirc CsJtj tj |¡¡d}ttƒD]}| tj |d|d¡|||¡qdS)Nrr}z-merged)rkrgÚsplitextÚbasenamergrrHrl)r<rOrÈrorqrrrrrIos "ÿz'XMLMenuBuilder.parse_default_merge_dirscCs’||jvr|jr td|ƒ‚dS|j |¡zt |¡}Wnty.|jr+td|ƒ‚YdS|jr9td|ƒ‚YdS| ¡}| |||¡dS)Nz Infinite MergeFile loop detectedrr) r#rrrr!r"ÚIOErrorr(r/)r<rÈrOrorÉÚrootrrrrjts"      zXMLMenuBuilder.merge_filecCs$| ||||¡}|r||7}dSdSr?)Úmerge_legacy_dir)r<rørårÈroÚmrrrrLŽs ÿzXMLMenuBuilder.parse_legacy_dirc CsJt||tƒ}|r¡||jvr£|j |¡tƒ}|j |¡|j |¡tj   |¡|_ d|_ t  |¡D]3}z(|dkr?|j |¡ntj  tj  ||¡¡rZ| | tj  ||¡|||¡¡Wq1tydYq1w|j |g|d¡|j |gd¡}|D]&}|j} t| ƒdkr‘t tj|j¡} |j | ¡||jvrž|  d¡| |_qx|SdSdS)NTz .directoryFrÚLegacy)rrr$rr&r1rCr4rkrgrqrr.rmr3rrlrDrtrnr&Úadd_menu_entriesÚget_menu_entriesrãrer´rÊrÔr]r9) r<rørårÈrorurorÖraÚ categoriesÚrrrrrt“sH     ü€ ÿ    €ÞzXMLMenuBuilder.merge_legacy_dircCs€ztjgd¢tjdd}| ¡d ¡}Wn tyYdSwz|d d¡D] }| |d||¡q(WdSty?YdSw)N)z kde-configz--pathÚappsT)ÚstdoutÚuniversal_newlinesrú:Úkde) Ú subprocessÚPopenÚPIPEÚ communicateÚ splitlinesÚOSErrorrdrLÚ IndexError)r<rÈroÚprocÚoutputrørrrrM¹s"ý þÿ ÿz$XMLMenuBuilder.parse_kde_legacy_dirscCs|jdurd|_|jdurd|_|jr|jsI|jr|j|_n+|jr1|jdkr,|jj|_ntƒ|_n|jdkrA|jj|_|jj|_ntƒ|_tƒ|_|jdkr^|jj|j|_|jj|j|_t|j ƒ|_ t|jƒ|_t|jƒ|_|j D]}|  |¡qs|j   ¡|j  ¡|j  ¡|j D]8}|jD],}t j t j ||¡¡r¾t||ƒ}|js«||_q’| ¡tjkr¾|j ¡tjkr¾||j_q’|jrÅdSqdS)NFr)r r8r5r2r,r-r1r4rr3r:r*rirkrgrrlr…r(rïrîrírà)r<r.rJrGrFrarrrr*ÊsR                      €ÿ÷zXMLMenuBuilder.post_parsecCs”|jD]}| |¡q|jdurF|j |j¡g}|jD] }| |j |j¡d¡}q|D]}|j durE|j   |¡d|_ d|_ |j   |¡q,dSdS)NFrcT)r:r+r8r&rwr1r9rØrxrÕrárCrÓr6©r<r.rJrÖrHrarrrr+s       €õz*XMLMenuBuilder.generate_not_only_allocatedcCsˆ|jD]}| |¡q|jdur@|j |j¡g}|jD] }| |j |j¡d¡}q|D]}|j dur?|j   |¡|j   |¡q,dSdS)NTrÑ) r:r,r8r&rwr1r9rØrxrÕrárCr6r‰rrrr,s       €öz&XMLMenuBuilder.generate_only_allocatedc CsÔ|jD]}| |¡q|jD]Y}| |j¡}|rg| |j¡}|j d¡}d}t|ƒdkr\|s0|}| |d¡}|sOtƒ}|d|_ t|ƒdkrJd|_ |  |¡|}|  d¡t|ƒdks,||7}|j j |¡qdS)NrbrrcT)r:r)r7rfr§r¨rdrer&rr.rDrjr-r•) r<r.rJrIÚmove_from_menuÚ move_to_menur}Ú oldparentr™rrrr)$s2            õ €êzXMLMenuBuilder.handle_movesr¡r?)r¢r£r¤r=r"r'r/rKrJrErSrVrArBrCrDrGrHrIrjrLrtrMr*r+r,r)rrrrrbs2  6 4"   $ &9 rc@s4eZdZdZdd„Zddd„Zdd „Zdd d „Zd S)r%zClass to cache Desktop EntriescCsi|_g|jd<i|_dS)NÚlegacy)Ú cacheEntriesr&r;rrrr=Cs  zMenuEntryCache.__init__r'FcCs2|D]}||jvrg|j|<| |d||¡qdS)Nr')rŽÚ_MenuEntryCache__addFiles)r<rrårrørrrrwHs   €ýzMenuEntryCache.add_menu_entriesc Cs²t tj ||¡¡D]L}| d¡r;z ttj ||¡||ƒ}Wn ty'Yq w|j| |¡|r:|jd |¡q tj  tj |||¡¡rV|sV|  |tj ||¡||¡q dS)Nz.desktopr) rkrmrgrlr r…rrŽrCrr)r<røÚsubdirrårrorarrrÚ __addFilesNs  ÿ€€õzMenuEntryCache.__addFilesTc Csâg}tƒ}|dd…}|r| d¡d |¡}z|j|WSty&Ynw|D]@}|j|D]8}z-|j|vrD| |j¡| |¡n| ¡t j kr^|  |¡} || } |  ¡t j kr^|| _ Wq0tyhYq0wq)||j|<|S)Nrr')rrCrlr&ÚKeyErrorrŽr]rrïr…rîÚindexríràrn) r<rrÚentriesÚidsÚappdirsÚkeyrøraÚidxr[rrrrx\s:     ÿ    € ÿõ zMenuEntryCache.get_menu_entriesN)r'F)T)r¢r£r¤r¥r=rwrrxrrrrr%As  r%FcCst|ƒ |¡S)zYHelper function. Equivalent to calling xdg.Menu.XMLMenuBuilder().parse(filename) )rr")rÈrrrrr"{sr"rý)1r¥rkrr€rr Úxml.etree.cElementTreer!Ú cElementTreeÚ ImportErrorÚxml.etree.ElementTreeÚ ElementTreeÚxdg.BaseDirectoryrrÚxdg.DesktopEntryrÚxdg.ExceptionsrÚxdg.utilrÚ xdg.LocalerÚ xdg.Configrrr„r‡r‰r”r’rŒr&r¦r5r´r…rxrŸrrrr rrÚobjectrr%r"rrrrÚsZ ÿ     1 /b  b: