home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / var / lib / python-support / python2.6 / xdg / MenuEditor.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  17.2 KB  |  558 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. ''' CLass to edit XDG Menus '''
  5. from xdg.Menu import *
  6. from xdg.BaseDirectory import *
  7. from xdg.Exceptions import *
  8. from xdg.DesktopEntry import *
  9. from xdg.Config import *
  10. import xml.dom.minidom as xml
  11. import os
  12. import re
  13.  
  14. class MenuEditor:
  15.     
  16.     def __init__(self, menu = None, filename = None, root = False):
  17.         self.menu = None
  18.         self.filename = None
  19.         self.doc = None
  20.         self.parse(menu, filename, root)
  21.         self.filenames = []
  22.  
  23.     
  24.     def parse(self, menu = None, filename = None, root = False):
  25.         if root == True:
  26.             setRootMode(True)
  27.         
  28.         if isinstance(menu, Menu):
  29.             self.menu = menu
  30.         elif menu:
  31.             self.menu = parse(menu)
  32.         else:
  33.             self.menu = parse()
  34.         if root == True:
  35.             self.filename = self.menu.Filename
  36.         elif filename:
  37.             self.filename = filename
  38.         else:
  39.             self.filename = os.path.join(xdg_config_dirs[0], 'menus', os.path.split(self.menu.Filename)[1])
  40.         
  41.         try:
  42.             self.doc = xml.dom.minidom.parse(self.filename)
  43.         except IOError:
  44.             self.doc = xml.dom.minidom.parseString('<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" "http://standards.freedesktop.org/menu-spec/menu-1.0.dtd"><Menu><Name>Applications</Name><MergeFile type="parent">' + self.menu.Filename + '</MergeFile></Menu>')
  45.         except xml.parsers.expat.ExpatError:
  46.             raise ParsingError('Not a valid .menu file', self.filename)
  47.  
  48.         self._MenuEditor__remove_whilespace_nodes(self.doc)
  49.  
  50.     
  51.     def save(self):
  52.         self._MenuEditor__saveEntries(self.menu)
  53.         self._MenuEditor__saveMenu()
  54.  
  55.     
  56.     def createMenuEntry(self, parent, name, command = None, genericname = None, comment = None, icon = None, terminal = None, after = None, before = None):
  57.         menuentry = MenuEntry(self._MenuEditor__getFileName(name, '.desktop'))
  58.         menuentry = self.editMenuEntry(menuentry, name, genericname, comment, command, icon, terminal)
  59.         self._MenuEditor__addEntry(parent, menuentry, after, before)
  60.         sort(self.menu)
  61.         return menuentry
  62.  
  63.     
  64.     def createMenu(self, parent, name, genericname = None, comment = None, icon = None, after = None, before = None):
  65.         menu = Menu()
  66.         menu.Parent = parent
  67.         menu.Depth = parent.Depth + 1
  68.         menu.Layout = parent.DefaultLayout
  69.         menu.DefaultLayout = parent.DefaultLayout
  70.         menu = self.editMenu(menu, name, genericname, comment, icon)
  71.         self._MenuEditor__addEntry(parent, menu, after, before)
  72.         sort(self.menu)
  73.         return menu
  74.  
  75.     
  76.     def createSeparator(self, parent, after = None, before = None):
  77.         separator = Separator(parent)
  78.         self._MenuEditor__addEntry(parent, separator, after, before)
  79.         sort(self.menu)
  80.         return separator
  81.  
  82.     
  83.     def moveMenuEntry(self, menuentry, oldparent, newparent, after = None, before = None):
  84.         self._MenuEditor__deleteEntry(oldparent, menuentry, after, before)
  85.         self._MenuEditor__addEntry(newparent, menuentry, after, before)
  86.         sort(self.menu)
  87.         return menuentry
  88.  
  89.     
  90.     def moveMenu(self, menu, oldparent, newparent, after = None, before = None):
  91.         self._MenuEditor__deleteEntry(oldparent, menu, after, before)
  92.         self._MenuEditor__addEntry(newparent, menu, after, before)
  93.         root_menu = self._MenuEditor__getXmlMenu(self.menu.Name)
  94.         if oldparent.getPath(True) != newparent.getPath(True):
  95.             self._MenuEditor__addXmlMove(root_menu, os.path.join(oldparent.getPath(True), menu.Name), os.path.join(newparent.getPath(True), menu.Name))
  96.         
  97.         sort(self.menu)
  98.         return menu
  99.  
  100.     
  101.     def moveSeparator(self, separator, parent, after = None, before = None):
  102.         self._MenuEditor__deleteEntry(parent, separator, after, before)
  103.         self._MenuEditor__addEntry(parent, separator, after, before)
  104.         sort(self.menu)
  105.         return separator
  106.  
  107.     
  108.     def copyMenuEntry(self, menuentry, oldparent, newparent, after = None, before = None):
  109.         self._MenuEditor__addEntry(newparent, menuentry, after, before)
  110.         sort(self.menu)
  111.         return menuentry
  112.  
  113.     
  114.     def editMenuEntry(self, menuentry, name = None, genericname = None, comment = None, command = None, icon = None, terminal = None, nodisplay = None, hidden = None):
  115.         deskentry = menuentry.DesktopEntry
  116.         if name:
  117.             if not deskentry.hasKey('Name'):
  118.                 deskentry.set('Name', name)
  119.             
  120.             deskentry.set('Name', name, locale = True)
  121.         
  122.         if comment:
  123.             if not deskentry.hasKey('Comment'):
  124.                 deskentry.set('Comment', comment)
  125.             
  126.             deskentry.set('Comment', comment, locale = True)
  127.         
  128.         if genericname:
  129.             if not deskentry.hasKey('GnericNe'):
  130.                 deskentry.set('GenericName', genericname)
  131.             
  132.             deskentry.set('GenericName', genericname, locale = True)
  133.         
  134.         if command:
  135.             deskentry.set('Exec', command)
  136.         
  137.         if icon:
  138.             deskentry.set('Icon', icon)
  139.         
  140.         if terminal == True:
  141.             deskentry.set('Terminal', 'true')
  142.         elif terminal == False:
  143.             deskentry.set('Terminal', 'false')
  144.         
  145.         if nodisplay == True:
  146.             deskentry.set('NoDisplay', 'true')
  147.         elif nodisplay == False:
  148.             deskentry.set('NoDisplay', 'false')
  149.         
  150.         if hidden == True:
  151.             deskentry.set('Hidden', 'true')
  152.         elif hidden == False:
  153.             deskentry.set('Hidden', 'false')
  154.         
  155.         menuentry.updateAttributes()
  156.         if len(menuentry.Parents) > 0:
  157.             sort(self.menu)
  158.         
  159.         return menuentry
  160.  
  161.     
  162.     def editMenu(self, menu, name = None, genericname = None, comment = None, icon = None, nodisplay = None, hidden = None):
  163.         if isinstance(menu.Directory, MenuEntry) and menu.Directory.Filename == '.directory':
  164.             xml_menu = self._MenuEditor__getXmlMenu(menu.getPath(True, True))
  165.             self._MenuEditor__addXmlTextElement(xml_menu, 'Directory', menu.Name + '.directory')
  166.             menu.Directory.setAttributes(menu.Name + '.directory')
  167.         elif not isinstance(menu.Directory, MenuEntry):
  168.             if not name:
  169.                 name = menu.Name
  170.             
  171.             filename = self._MenuEditor__getFileName(name, '.directory').replace('/', '')
  172.             if not menu.Name:
  173.                 menu.Name = filename.replace('.directory', '')
  174.             
  175.             xml_menu = self._MenuEditor__getXmlMenu(menu.getPath(True, True))
  176.             self._MenuEditor__addXmlTextElement(xml_menu, 'Directory', filename)
  177.             menu.Directory = MenuEntry(filename)
  178.         
  179.         deskentry = menu.Directory.DesktopEntry
  180.         if name:
  181.             if not deskentry.hasKey('Name'):
  182.                 deskentry.set('Name', name)
  183.             
  184.             deskentry.set('Name', name, locale = True)
  185.         
  186.         if genericname:
  187.             if not deskentry.hasKey('GenericName'):
  188.                 deskentry.set('GenericName', genericname)
  189.             
  190.             deskentry.set('GenericName', genericname, locale = True)
  191.         
  192.         if comment:
  193.             if not deskentry.hasKey('Comment'):
  194.                 deskentry.set('Comment', comment)
  195.             
  196.             deskentry.set('Comment', comment, locale = True)
  197.         
  198.         if icon:
  199.             deskentry.set('Icon', icon)
  200.         
  201.         if nodisplay == True:
  202.             deskentry.set('NoDisplay', 'true')
  203.         elif nodisplay == False:
  204.             deskentry.set('NoDisplay', 'false')
  205.         
  206.         if hidden == True:
  207.             deskentry.set('Hidden', 'true')
  208.         elif hidden == False:
  209.             deskentry.set('Hidden', 'false')
  210.         
  211.         menu.Directory.updateAttributes()
  212.         if isinstance(menu.Parent, Menu):
  213.             sort(self.menu)
  214.         
  215.         return menu
  216.  
  217.     
  218.     def hideMenuEntry(self, menuentry):
  219.         self.editMenuEntry(menuentry, nodisplay = True)
  220.  
  221.     
  222.     def unhideMenuEntry(self, menuentry):
  223.         self.editMenuEntry(menuentry, nodisplay = False, hidden = False)
  224.  
  225.     
  226.     def hideMenu(self, menu):
  227.         self.editMenu(menu, nodisplay = True)
  228.  
  229.     
  230.     def unhideMenu(self, menu):
  231.         self.editMenu(menu, nodisplay = False, hidden = False)
  232.         xml_menu = self._MenuEditor__getXmlMenu(menu.getPath(True, True), False)
  233.         for node in self._MenuEditor__getXmlNodesByName([
  234.             'Deleted',
  235.             'NotDeleted'], xml_menu):
  236.             node.parentNode.removeChild(node)
  237.         
  238.  
  239.     
  240.     def deleteMenuEntry(self, menuentry):
  241.         if self.getAction(menuentry) == 'delete':
  242.             self._MenuEditor__deleteFile(menuentry.DesktopEntry.filename)
  243.             for parent in menuentry.Parents:
  244.                 self._MenuEditor__deleteEntry(parent, menuentry)
  245.             
  246.             sort(self.menu)
  247.         
  248.         return menuentry
  249.  
  250.     
  251.     def revertMenuEntry(self, menuentry):
  252.         if self.getAction(menuentry) == 'revert':
  253.             self._MenuEditor__deleteFile(menuentry.DesktopEntry.filename)
  254.             menuentry.Original.Parents = []
  255.             for parent in menuentry.Parents:
  256.                 index = parent.Entries.index(menuentry)
  257.                 parent.Entries[index] = menuentry.Original
  258.                 index = parent.MenuEntries.index(menuentry)
  259.                 parent.MenuEntries[index] = menuentry.Original
  260.                 menuentry.Original.Parents.append(parent)
  261.             
  262.             sort(self.menu)
  263.         
  264.         return menuentry
  265.  
  266.     
  267.     def deleteMenu(self, menu):
  268.         if self.getAction(menu) == 'delete':
  269.             self._MenuEditor__deleteFile(menu.Directory.DesktopEntry.filename)
  270.             self._MenuEditor__deleteEntry(menu.Parent, menu)
  271.             xml_menu = self._MenuEditor__getXmlMenu(menu.getPath(True, True))
  272.             xml_menu.parentNode.removeChild(xml_menu)
  273.             sort(self.menu)
  274.         
  275.         return menu
  276.  
  277.     
  278.     def revertMenu(self, menu):
  279.         if self.getAction(menu) == 'revert':
  280.             self._MenuEditor__deleteFile(menu.Directory.DesktopEntry.filename)
  281.             menu.Directory = menu.Directory.Original
  282.             sort(self.menu)
  283.         
  284.         return menu
  285.  
  286.     
  287.     def deleteSeparator(self, separator):
  288.         self._MenuEditor__deleteEntry(separator.Parent, separator, after = True)
  289.         sort(self.menu)
  290.         return separator
  291.  
  292.     
  293.     def getAction(self, entry):
  294.         if isinstance(entry, Menu):
  295.             if not isinstance(entry.Directory, MenuEntry):
  296.                 return 'none'
  297.             if entry.Directory.getType() == 'Both':
  298.                 return 'revert'
  299.             if entry.Directory.getType() == 'User' and len(entry.Submenus) + len(entry.MenuEntries) == 0:
  300.                 return 'delete'
  301.         elif isinstance(entry, MenuEntry):
  302.             if entry.getType() == 'Both':
  303.                 return 'revert'
  304.             if entry.getType() == 'User':
  305.                 return 'delete'
  306.             return 'none'
  307.         
  308.         return 'none'
  309.  
  310.     
  311.     def __saveEntries(self, menu):
  312.         if not menu:
  313.             menu = self.menu
  314.         
  315.         if isinstance(menu.Directory, MenuEntry):
  316.             menu.Directory.save()
  317.         
  318.         for entry in menu.getEntries(hidden = True):
  319.             if isinstance(entry, MenuEntry):
  320.                 entry.save()
  321.                 continue
  322.             if isinstance(entry, Menu):
  323.                 self._MenuEditor__saveEntries(entry)
  324.                 continue
  325.         
  326.  
  327.     
  328.     def __saveMenu(self):
  329.         if not os.path.isdir(os.path.dirname(self.filename)):
  330.             os.makedirs(os.path.dirname(self.filename))
  331.         
  332.         fd = open(self.filename, 'w')
  333.         fd.write(re.sub('\n[\\s]*([^\n<]*)\n[\\s]*</', '\\1</', self.doc.toprettyxml().replace('<?xml version="1.0" ?>\n', '')))
  334.         fd.close()
  335.  
  336.     
  337.     def __getFileName(self, name, extension):
  338.         postfix = 0
  339.         while postfix == 0:
  340.             filename = name + extension
  341.         filename = name + '-' + str(postfix) + extension
  342.         if extension == '.desktop':
  343.             dir = 'applications'
  344.         elif extension == '.directory':
  345.             dir = 'desktop-directories'
  346.         
  347.         if filename not in self.filenames and not os.path.isfile(os.path.join(xdg_data_dirs[0], dir, filename)):
  348.             self.filenames.append(filename)
  349.             break
  350.             continue
  351.         postfix += 1
  352.         continue
  353.         return filename
  354.  
  355.     
  356.     def __getXmlMenu(self, path, create = True, element = None):
  357.         if not element:
  358.             element = self.doc
  359.         
  360.         if '/' in path:
  361.             (name, path) = path.split('/', 1)
  362.         else:
  363.             name = path
  364.             path = ''
  365.         found = None
  366.         for node in self._MenuEditor__getXmlNodesByName('Menu', element):
  367.             for child in self._MenuEditor__getXmlNodesByName('Name', node):
  368.                 if child.childNodes[0].nodeValue == name:
  369.                     if path:
  370.                         found = self._MenuEditor__getXmlMenu(path, create, node)
  371.                     else:
  372.                         found = node
  373.                     break
  374.                     continue
  375.             
  376.             if found:
  377.                 break
  378.                 continue
  379.         
  380.         if not found and create == True:
  381.             node = self._MenuEditor__addXmlMenuElement(element, name)
  382.             if path:
  383.                 found = self._MenuEditor__getXmlMenu(path, create, node)
  384.             else:
  385.                 found = node
  386.         
  387.         return found
  388.  
  389.     
  390.     def __addXmlMenuElement(self, element, name):
  391.         node = self.doc.createElement('Menu')
  392.         self._MenuEditor__addXmlTextElement(node, 'Name', name)
  393.         return element.appendChild(node)
  394.  
  395.     
  396.     def __addXmlTextElement(self, element, name, text):
  397.         node = self.doc.createElement(name)
  398.         text = self.doc.createTextNode(text)
  399.         node.appendChild(text)
  400.         return element.appendChild(node)
  401.  
  402.     
  403.     def __addXmlFilename(self, element, filename, type = 'Include'):
  404.         for node in self._MenuEditor__getXmlNodesByName([
  405.             'Include',
  406.             'Exclude'], element):
  407.             if node.childNodes[0].nodeName == 'Filename' and node.childNodes[0].childNodes[0].nodeValue == filename:
  408.                 element.removeChild(node)
  409.                 continue
  410.         
  411.         node = self.doc.createElement(type)
  412.         node.appendChild(self._MenuEditor__addXmlTextElement(node, 'Filename', filename))
  413.         return element.appendChild(node)
  414.  
  415.     
  416.     def __addXmlMove(self, element, old, new):
  417.         node = self.doc.createElement('Move')
  418.         node.appendChild(self._MenuEditor__addXmlTextElement(node, 'Old', old))
  419.         node.appendChild(self._MenuEditor__addXmlTextElement(node, 'New', new))
  420.         return element.appendChild(node)
  421.  
  422.     
  423.     def __addXmlLayout(self, element, layout):
  424.         for node in self._MenuEditor__getXmlNodesByName('Layout', element):
  425.             element.removeChild(node)
  426.         
  427.         node = self.doc.createElement('Layout')
  428.         for order in layout.order:
  429.             if order[0] == 'Separator':
  430.                 child = self.doc.createElement('Separator')
  431.                 node.appendChild(child)
  432.                 continue
  433.             if order[0] == 'Filename':
  434.                 child = self._MenuEditor__addXmlTextElement(node, 'Filename', order[1])
  435.                 continue
  436.             if order[0] == 'Menuname':
  437.                 child = self._MenuEditor__addXmlTextElement(node, 'Menuname', order[1])
  438.                 continue
  439.             if order[0] == 'Merge':
  440.                 child = self.doc.createElement('Merge')
  441.                 child.setAttribute('type', order[1])
  442.                 node.appendChild(child)
  443.                 continue
  444.         
  445.         return element.appendChild(node)
  446.  
  447.     
  448.     def __getXmlNodesByName(self, name, element):
  449.         for child in element.childNodes:
  450.             if child.nodeType == xml.dom.Node.ELEMENT_NODE and child.nodeName in name:
  451.                 yield child
  452.                 continue
  453.         
  454.  
  455.     
  456.     def __addLayout(self, parent):
  457.         layout = Layout()
  458.         layout.order = []
  459.         layout.show_empty = parent.Layout.show_empty
  460.         layout.inline = parent.Layout.inline
  461.         layout.inline_header = parent.Layout.inline_header
  462.         layout.inline_alias = parent.Layout.inline_alias
  463.         layout.inline_limit = parent.Layout.inline_limit
  464.         layout.order.append([
  465.             'Merge',
  466.             'menus'])
  467.         for entry in parent.Entries:
  468.             if isinstance(entry, Menu):
  469.                 layout.parseMenuname(entry.Name)
  470.                 continue
  471.             if isinstance(entry, MenuEntry):
  472.                 layout.parseFilename(entry.DesktopFileID)
  473.                 continue
  474.             if isinstance(entry, Separator):
  475.                 layout.parseSeparator()
  476.                 continue
  477.         
  478.         layout.order.append([
  479.             'Merge',
  480.             'files'])
  481.         parent.Layout = layout
  482.         return layout
  483.  
  484.     
  485.     def __addEntry(self, parent, entry, after = None, before = None):
  486.         if after or before:
  487.             if after:
  488.                 index = parent.Entries.index(after) + 1
  489.             elif before:
  490.                 index = parent.Entries.index(before)
  491.             
  492.             parent.Entries.insert(index, entry)
  493.         else:
  494.             parent.Entries.append(entry)
  495.         xml_parent = self._MenuEditor__getXmlMenu(parent.getPath(True, True))
  496.         if isinstance(entry, MenuEntry):
  497.             parent.MenuEntries.append(entry)
  498.             entry.Parents.append(parent)
  499.             self._MenuEditor__addXmlFilename(xml_parent, entry.DesktopFileID, 'Include')
  500.         elif isinstance(entry, Menu):
  501.             parent.addSubmenu(entry)
  502.         
  503.         if after or before:
  504.             self._MenuEditor__addLayout(parent)
  505.             self._MenuEditor__addXmlLayout(xml_parent, parent.Layout)
  506.         
  507.  
  508.     
  509.     def __deleteEntry(self, parent, entry, after = None, before = None):
  510.         parent.Entries.remove(entry)
  511.         xml_parent = self._MenuEditor__getXmlMenu(parent.getPath(True, True))
  512.         if isinstance(entry, MenuEntry):
  513.             entry.Parents.remove(parent)
  514.             parent.MenuEntries.remove(entry)
  515.             self._MenuEditor__addXmlFilename(xml_parent, entry.DesktopFileID, 'Exclude')
  516.         elif isinstance(entry, Menu):
  517.             parent.Submenus.remove(entry)
  518.         
  519.         if after or before:
  520.             self._MenuEditor__addLayout(parent)
  521.             self._MenuEditor__addXmlLayout(xml_parent, parent.Layout)
  522.         
  523.  
  524.     
  525.     def __deleteFile(self, filename):
  526.         
  527.         try:
  528.             os.remove(filename)
  529.         except OSError:
  530.             pass
  531.  
  532.         
  533.         try:
  534.             self.filenames.remove(filename)
  535.         except ValueError:
  536.             pass
  537.  
  538.  
  539.     
  540.     def __remove_whilespace_nodes(self, node):
  541.         remove_list = []
  542.         for child in node.childNodes:
  543.             if child.nodeType == xml.dom.minidom.Node.TEXT_NODE:
  544.                 child.data = child.data.strip()
  545.                 if not child.data.strip():
  546.                     remove_list.append(child)
  547.                 
  548.             child.data.strip()
  549.             if child.hasChildNodes():
  550.                 self._MenuEditor__remove_whilespace_nodes(child)
  551.                 continue
  552.         
  553.         for node in remove_list:
  554.             node.parentNode.removeChild(node)
  555.         
  556.  
  557.  
  558.