home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / python2.4 / site-packages / Alacarte / MenuEditor.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-07-25  |  25.4 KB  |  900 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. import os
  5. import re
  6. import xml.dom.minidom as xml
  7. import locale
  8. import gmenu
  9. from Alacarte import util
  10.  
  11. class Menu:
  12.     tree = None
  13.     visible_tree = None
  14.     path = None
  15.     dom = None
  16.  
  17.  
  18. class MenuEditor:
  19.     __undo = []
  20.     __redo = []
  21.     
  22.     def __init__(self):
  23.         self.locale = locale.getdefaultlocale()[0]
  24.         self._MenuEditor__loadMenus()
  25.  
  26.     
  27.     def __loadMenus(self):
  28.         self.applications = Menu()
  29.         self.applications.tree = gmenu.lookup_tree('applications.menu', gmenu.FLAGS_SHOW_EMPTY | gmenu.FLAGS_INCLUDE_EXCLUDED | gmenu.FLAGS_INCLUDE_NODISPLAY)
  30.         self.applications.visible_tree = gmenu.lookup_tree('applications.menu')
  31.         self.applications.path = os.path.join(util.getUserMenuPath(), self.applications.tree.get_menu_file())
  32.         if not os.path.isfile(self.applications.path):
  33.             self.applications.dom = xml.dom.minidom.parseString(util.getUserMenuXml(self.applications.tree))
  34.         else:
  35.             self.applications.dom = xml.dom.minidom.parse(self.applications.path)
  36.         self._MenuEditor__remove_whilespace_nodes(self.applications.dom)
  37.         self.settings = Menu()
  38.         self.settings.tree = gmenu.lookup_tree('settings.menu', gmenu.FLAGS_SHOW_EMPTY | gmenu.FLAGS_INCLUDE_EXCLUDED | gmenu.FLAGS_INCLUDE_NODISPLAY)
  39.         self.settings.visible_tree = gmenu.lookup_tree('settings.menu')
  40.         self.settings.path = os.path.join(util.getUserMenuPath(), self.settings.tree.get_menu_file())
  41.         if not os.path.isfile(self.settings.path):
  42.             self.settings.dom = xml.dom.minidom.parseString(util.getUserMenuXml(self.settings.tree))
  43.         else:
  44.             self.settings.dom = xml.dom.minidom.parse(self.settings.path)
  45.         self._MenuEditor__remove_whilespace_nodes(self.settings.dom)
  46.         self.save(True)
  47.  
  48.     
  49.     def save(self, from_loading = False):
  50.         for menu in ('applications', 'settings'):
  51.             fd = open(getattr(self, menu).path, 'w')
  52.             fd.write(re.sub('\n[\\s]*([^\n<]*)\n[\\s]*</', '\\1</', getattr(self, menu).dom.toprettyxml().replace('<?xml version="1.0" ?>\n', '')))
  53.             fd.close()
  54.         
  55.         if not from_loading:
  56.             self._MenuEditor__loadMenus()
  57.         
  58.  
  59.     
  60.     def quit(self):
  61.         for file_name in os.listdir(util.getUserItemPath()):
  62.             if file_name[-6:-2] in ('redo', 'undo'):
  63.                 file_path = os.path.join(util.getUserItemPath(), file_name)
  64.                 os.unlink(file_path)
  65.                 continue
  66.         
  67.         for file_name in os.listdir(util.getUserDirectoryPath()):
  68.             if file_name[-6:-2] in ('redo', 'undo'):
  69.                 file_path = os.path.join(util.getUserDirectoryPath(), file_name)
  70.                 os.unlink(file_path)
  71.                 continue
  72.         
  73.         for file_name in os.listdir(util.getUserMenuPath()):
  74.             if file_name[-6:-2] in ('redo', 'undo'):
  75.                 file_path = os.path.join(util.getUserMenuPath(), file_name)
  76.                 os.unlink(file_path)
  77.                 continue
  78.         
  79.  
  80.     
  81.     def revert(self):
  82.         for name in ('applications', 'settings'):
  83.             menu = getattr(self, name)
  84.             self.revertTree(menu.tree.root)
  85.             path = os.path.join(util.getUserMenuPath(), menu.tree.get_menu_file())
  86.             
  87.             try:
  88.                 os.unlink(path)
  89.             except OSError:
  90.                 pass
  91.  
  92.             if not os.path.isfile(menu.path):
  93.                 menu.dom = xml.dom.minidom.parseString(util.getUserMenuXml(menu.tree))
  94.             else:
  95.                 menu.dom = xml.dom.minidom.parse(menu.path)
  96.             self._MenuEditor__remove_whilespace_nodes(menu.dom)
  97.             self._MenuEditor__undo = []
  98.             self._MenuEditor__redo = []
  99.         
  100.         self.save()
  101.  
  102.     
  103.     def revertTree(self, menu):
  104.         for child in menu.get_contents():
  105.             if child.get_type() == gmenu.TYPE_DIRECTORY:
  106.                 self.revertTree(child)
  107.                 continue
  108.             if child.get_type() == gmenu.TYPE_ENTRY:
  109.                 self.revertItem(child)
  110.                 continue
  111.         
  112.         self.revertMenu(menu)
  113.  
  114.     
  115.     def undo(self):
  116.         if len(self._MenuEditor__undo) == 0:
  117.             return None
  118.         
  119.         files = self._MenuEditor__undo.pop()
  120.         redo = []
  121.         for file_path in files:
  122.             new_path = file_path.rsplit('.', 1)[0]
  123.             redo_path = util.getUniqueRedoFile(new_path)
  124.             data = open(new_path).read()
  125.             open(redo_path, 'w').write(data)
  126.             data = open(file_path).read()
  127.             open(new_path, 'w').write(data)
  128.             os.unlink(file_path)
  129.             redo.append(redo_path)
  130.         
  131.         for name in ('applications', 'settings'):
  132.             menu = getattr(self, name)
  133.             if not os.path.isfile(menu.path):
  134.                 menu.dom = xml.dom.minidom.parseString(util.getUserMenuXml(menu.tree))
  135.             else:
  136.                 menu.dom = xml.dom.minidom.parse(menu.path)
  137.             self._MenuEditor__remove_whilespace_nodes(menu.dom)
  138.         
  139.         self._MenuEditor__redo.append(redo)
  140.  
  141.     
  142.     def redo(self):
  143.         if len(self._MenuEditor__redo) == 0:
  144.             return None
  145.         
  146.         files = self._MenuEditor__redo.pop()
  147.         undo = []
  148.         for file_path in files:
  149.             new_path = file_path.rsplit('.', 1)[0]
  150.             undo_path = util.getUniqueUndoFile(new_path)
  151.             data = open(new_path).read()
  152.             open(undo_path, 'w').write(data)
  153.             data = open(file_path).read()
  154.             open(new_path, 'w').write(data)
  155.             os.unlink(file_path)
  156.             undo.append(undo_path)
  157.         
  158.         for name in ('applications', 'settings'):
  159.             menu = getattr(self, name)
  160.             if not os.path.isfile(menu.path):
  161.                 menu.dom = xml.dom.minidom.parseString(util.getUserMenuXml(menu.tree))
  162.             else:
  163.                 menu.dom = xml.dom.minidom.parse(menu.path)
  164.             self._MenuEditor__remove_whilespace_nodes(menu.dom)
  165.         
  166.         self._MenuEditor__undo.append(undo)
  167.  
  168.     
  169.     def getMenus(self, parent = None):
  170.         if parent == None:
  171.             yield self.applications.tree.root
  172.             yield self.settings.tree.root
  173.         else:
  174.             for menu in parent.get_contents():
  175.                 if menu.get_type() == gmenu.TYPE_DIRECTORY:
  176.                     yield (menu, self._MenuEditor__isVisible(menu))
  177.                     continue
  178.             
  179.  
  180.     
  181.     def getItems(self, menu):
  182.         for item in menu.get_contents():
  183.             if item.get_type() == gmenu.TYPE_SEPARATOR:
  184.                 yield (item, True)
  185.                 continue
  186.             if item.get_type() == gmenu.TYPE_ENTRY and item.get_desktop_file_id()[-19:] == '-usercustom.desktop':
  187.                 continue
  188.             
  189.             yield (item, self._MenuEditor__isVisible(item))
  190.         
  191.  
  192.     
  193.     def canRevert(self, item):
  194.         if item.get_type() == gmenu.TYPE_ENTRY:
  195.             if util.getItemPath(item.get_desktop_file_id()):
  196.                 path = util.getUserItemPath()
  197.                 if os.path.isfile(os.path.join(path, item.get_desktop_file_id())):
  198.                     return True
  199.                 
  200.             
  201.         elif item.get_type() == gmenu.TYPE_DIRECTORY:
  202.             if item.get_desktop_file_path():
  203.                 file_id = os.path.split(item.get_desktop_file_path())[1]
  204.             else:
  205.                 file_id = item.get_menu_id() + '.directory'
  206.             if util.getDirectoryPath(file_id):
  207.                 path = util.getUserDirectoryPath()
  208.                 if os.path.isfile(os.path.join(path, file_id)):
  209.                     return True
  210.                 
  211.             
  212.         
  213.         return False
  214.  
  215.     
  216.     def setVisible(self, item, visible):
  217.         dom = self._MenuEditor__getMenu(item).dom
  218.         if item.get_type() == gmenu.TYPE_ENTRY:
  219.             self._MenuEditor__addUndo([
  220.                 self._MenuEditor__getMenu(item),
  221.                 item])
  222.             menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(item.get_parent()), dom, dom)
  223.             if visible:
  224.                 self._MenuEditor__addXmlFilename(menu_xml, dom, item.get_desktop_file_id(), 'Include')
  225.                 self._MenuEditor__writeItem(item, no_display = False)
  226.             else:
  227.                 self._MenuEditor__addXmlFilename(menu_xml, dom, item.get_desktop_file_id(), 'Exclude')
  228.             self._MenuEditor__addXmlTextElement(menu_xml, 'AppDir', util.getUserItemPath(), dom)
  229.         elif item.get_type() == gmenu.TYPE_DIRECTORY:
  230.             self._MenuEditor__addUndo([
  231.                 self._MenuEditor__getMenu(item),
  232.                 item])
  233.             if len(item.get_contents()) == 0:
  234.                 return None
  235.             
  236.             menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(item), dom, dom)
  237.             for node in self._MenuEditor__getXmlNodesByName([
  238.                 'Deleted',
  239.                 'NotDeleted'], menu_xml):
  240.                 node.parentNode.removeChild(node)
  241.             
  242.             if visible:
  243.                 self._MenuEditor__writeMenu(item, no_display = False)
  244.             else:
  245.                 self._MenuEditor__writeMenu(item, no_display = True)
  246.             self._MenuEditor__addXmlTextElement(menu_xml, 'DirectoryDir', util.getUserDirectoryPath(), dom)
  247.         
  248.         self.save()
  249.  
  250.     
  251.     def createItem(self, parent, icon, name, comment, command, use_term, before = None, after = None):
  252.         file_id = self._MenuEditor__writeItem(None, icon, name, comment, command, use_term)
  253.         dom = self._MenuEditor__getMenu(parent).dom
  254.         self._MenuEditor__addItem(parent, file_id, dom)
  255.         self._MenuEditor__positionItem(parent, ('Item', file_id), before, after)
  256.         self._MenuEditor__addUndo([
  257.             self._MenuEditor__getMenu(parent),
  258.             ('Item', file_id)])
  259.         self.save()
  260.  
  261.     
  262.     def createMenu(self, parent, icon, name, comment, before = None, after = None):
  263.         file_id = self._MenuEditor__writeMenu(None, icon, name, comment)
  264.         menu_id = file_id.rsplit('.', 1)[0]
  265.         dom = self._MenuEditor__getMenu(parent).dom
  266.         menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent) + '/' + menu_id, dom, dom)
  267.         self._MenuEditor__addXmlTextElement(menu_xml, 'Directory', file_id, dom)
  268.         self._MenuEditor__positionItem(parent, ('Menu', menu_id), before, after)
  269.         self._MenuEditor__addUndo([
  270.             self._MenuEditor__getMenu(parent),
  271.             ('Menu', file_id)])
  272.         self.save()
  273.  
  274.     
  275.     def createSeparator(self, parent, before = None, after = None):
  276.         self._MenuEditor__positionItem(parent, ('Separator',), before, after)
  277.         self._MenuEditor__addUndo([
  278.             self._MenuEditor__getMenu(parent),
  279.             ('Separator',)])
  280.         self.save()
  281.  
  282.     
  283.     def editItem(self, item, icon, name, comment, command, use_term, parent = None, final = True):
  284.         if icon == item.get_icon() and name == item.get_name() and comment == item.get_comment() and command == item.get_exec() and use_term == item.get_launch_in_terminal():
  285.             return None
  286.         
  287.         if not parent:
  288.             parent = item.get_parent()
  289.         
  290.         if final:
  291.             self._MenuEditor__addUndo([
  292.                 self._MenuEditor__getMenu(parent),
  293.                 item])
  294.         
  295.         self._MenuEditor__writeItem(item, icon, name, comment, command, use_term)
  296.         if final:
  297.             dom = self._MenuEditor__getMenu(parent).dom
  298.             menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent), dom, dom)
  299.             self._MenuEditor__addXmlTextElement(menu_xml, 'AppDir', util.getUserItemPath(), dom)
  300.         
  301.         self.save()
  302.  
  303.     
  304.     def editMenu(self, menu, icon, name, comment, final = True):
  305.         if icon == menu.get_icon() and name == menu.get_name() and comment == menu.get_comment():
  306.             return None
  307.         
  308.         dom = self._MenuEditor__getMenu(menu).dom
  309.         menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(menu), dom, dom)
  310.         file_id = self._MenuEditor__writeMenu(menu, icon, name, comment)
  311.         if final:
  312.             self._MenuEditor__addXmlTextElement(menu_xml, 'DirectoryDir', util.getUserDirectoryPath(), dom)
  313.             self._MenuEditor__addUndo([
  314.                 self._MenuEditor__getMenu(menu),
  315.                 menu])
  316.         
  317.         self.save()
  318.  
  319.     
  320.     def copyItem(self, item, new_parent, before = None, after = None):
  321.         dom = self._MenuEditor__getMenu(new_parent).dom
  322.         file_path = item.get_desktop_file_path()
  323.         keyfile = util.DesktopParser(file_path)
  324.         keyfile.set('Categories', ('',))
  325.         keyfile.set('Hidden', False)
  326.         file_id = util.getUniqueFileId(item.get_name(), '.desktop')
  327.         out_path = os.path.join(util.getUserItemPath(), file_id)
  328.         keyfile.write(open(out_path, 'w'))
  329.         self._MenuEditor__addItem(new_parent, file_id, dom)
  330.         self._MenuEditor__positionItem(new_parent, ('Item', file_id), before, after)
  331.         self._MenuEditor__addUndo([
  332.             self._MenuEditor__getMenu(new_parent),
  333.             ('Item', file_id)])
  334.         self.save()
  335.         return file_id
  336.  
  337.     
  338.     def moveItem(self, item, new_parent, before = None, after = None):
  339.         undo = []
  340.         if item.get_parent() != new_parent:
  341.             self.deleteItem(item)
  342.             undo.append(item)
  343.             file_id = self.copyItem(item, new_parent)
  344.             item = ('Item', file_id)
  345.             undo.append(item)
  346.         
  347.         self._MenuEditor__positionItem(new_parent, item, before, after)
  348.         undo.append(self._MenuEditor__getMenu(new_parent))
  349.         self._MenuEditor__addUndo(undo)
  350.         self.save()
  351.  
  352.     
  353.     def moveMenu(self, menu, new_parent, before = None, after = None):
  354.         parent = new_parent
  355.         while parent.get_parent():
  356.             parent = parent.get_parent()
  357.             if parent == menu:
  358.                 return False
  359.                 continue
  360.         if self._MenuEditor__getMenu(menu) != self._MenuEditor__getMenu(new_parent):
  361.             return False
  362.         
  363.         if menu.get_parent() != new_parent:
  364.             dom = self._MenuEditor__getMenu(menu).dom
  365.             root_path = self._MenuEditor__getPath(menu).split('/', 1)[0]
  366.             xml_root = self._MenuEditor__getXmlMenu(root_path, dom, dom)
  367.             old_path = self._MenuEditor__getPath(menu).split('/', 1)[1]
  368.             if '/' in self._MenuEditor__getPath(new_parent):
  369.                 new_path = self._MenuEditor__getPath(new_parent).split('/', 1)[1] + '/' + menu.get_menu_id()
  370.             else:
  371.                 new_path = menu.get_menu_id()
  372.             self._MenuEditor__addXmlMove(xml_root, old_path, new_path, dom)
  373.         
  374.         self._MenuEditor__positionItem(new_parent, menu, before, after)
  375.         self._MenuEditor__addUndo([
  376.             self._MenuEditor__getMenu(new_parent)])
  377.         self.save()
  378.  
  379.     
  380.     def moveSeparator(self, separator, new_parent, before = None, after = None):
  381.         self._MenuEditor__positionItem(new_parent, separator, before, after)
  382.         self._MenuEditor__addUndo([
  383.             self._MenuEditor__getMenu(new_parent)])
  384.         self.save()
  385.  
  386.     
  387.     def deleteItem(self, item):
  388.         self._MenuEditor__writeItem(item, hidden = True)
  389.         self._MenuEditor__addUndo([
  390.             item])
  391.         self.save()
  392.  
  393.     
  394.     def deleteMenu(self, menu):
  395.         dom = self._MenuEditor__getMenu(menu).dom
  396.         menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(menu), dom, dom)
  397.         self._MenuEditor__addDeleted(menu_xml, dom)
  398.         self._MenuEditor__addUndo([
  399.             self._MenuEditor__getMenu(menu)])
  400.         self.save()
  401.  
  402.     
  403.     def deleteSeparator(self, item):
  404.         parent = item.get_parent()
  405.         contents = parent.get_contents()
  406.         contents.remove(item)
  407.         layout = self._MenuEditor__createLayout(contents)
  408.         dom = self._MenuEditor__getMenu(parent).dom
  409.         menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent), dom, dom)
  410.         self._MenuEditor__addXmlLayout(menu_xml, layout, dom)
  411.         self._MenuEditor__addUndo([
  412.             self._MenuEditor__getMenu(item.get_parent())])
  413.         self.save()
  414.  
  415.     
  416.     def revertItem(self, item):
  417.         if not self.canRevert(item):
  418.             return None
  419.         
  420.         self._MenuEditor__addUndo([
  421.             item])
  422.         
  423.         try:
  424.             os.remove(item.get_desktop_file_path())
  425.         except OSError:
  426.             pass
  427.  
  428.         self.save()
  429.  
  430.     
  431.     def revertMenu(self, menu):
  432.         if not self.canRevert(menu):
  433.             return None
  434.         
  435.         self._MenuEditor__addUndo([
  436.             menu])
  437.         file_id = os.path.split(menu.get_desktop_file_path())[1]
  438.         path = os.path.join(util.getUserDirectoryPath(), file_id)
  439.         
  440.         try:
  441.             os.remove(path)
  442.         except OSError:
  443.             pass
  444.  
  445.         self.save()
  446.  
  447.     
  448.     def __addUndo(self, items):
  449.         self._MenuEditor__undo.append([])
  450.         for item in items:
  451.             if isinstance(item, Menu):
  452.                 file_path = item.path
  453.             elif isinstance(item, tuple):
  454.                 if item[0] == 'Item':
  455.                     file_path = os.path.join(util.getUserItemPath(), item[1])
  456.                     if not os.path.isfile(file_path):
  457.                         file_path = util.getItemPath(item[1])
  458.                     
  459.                 elif item[0] == 'Menu':
  460.                     file_path = os.path.join(util.getUserDirectoryPath(), item[1])
  461.                     if not os.path.isfile(file_path):
  462.                         file_path = util.getDirectoryPath(item[1])
  463.                     
  464.                 
  465.             elif item.get_type() == gmenu.TYPE_DIRECTORY:
  466.                 file_path = os.path.join(util.getUserDirectoryPath(), os.path.split(item.get_desktop_file_path())[1])
  467.                 if not os.path.isfile(file_path):
  468.                     file_path = item.get_desktop_file_path()
  469.                 
  470.             elif item.get_type() == gmenu.TYPE_ENTRY:
  471.                 file_path = os.path.join(util.getUserItemPath(), item.get_desktop_file_id())
  472.                 if not os.path.isfile(file_path):
  473.                     file_path = item.get_desktop_file_path()
  474.                 
  475.             
  476.             data = open(file_path).read()
  477.             undo_path = util.getUniqueUndoFile(file_path)
  478.             open(undo_path, 'w').write(data)
  479.             self._MenuEditor__undo[-1].append(undo_path)
  480.         
  481.  
  482.     
  483.     def __getMenu(self, item):
  484.         root = item.get_parent()
  485.         if not root:
  486.             root = item
  487.         else:
  488.             while True:
  489.                 if root.get_parent():
  490.                     root = root.get_parent()
  491.                     continue
  492.                 break
  493.         if root.menu_id == self.applications.tree.root.menu_id:
  494.             return self.applications
  495.         
  496.         return self.settings
  497.  
  498.     
  499.     def __isVisible(self, item):
  500.         if item.get_type() == gmenu.TYPE_ENTRY:
  501.             if not item.get_is_excluded():
  502.                 pass
  503.             return not item.get_is_nodisplay()
  504.         
  505.         
  506.         def loop_for_menu(parent, menu):
  507.             for item in parent.get_contents():
  508.                 if item.get_type() == gmenu.TYPE_DIRECTORY:
  509.                     if item.menu_id == menu.menu_id:
  510.                         return True
  511.                     
  512.                     temp = loop_for_menu(item, menu)
  513.                     if temp:
  514.                         return True
  515.                     
  516.                 temp
  517.             
  518.             return False
  519.  
  520.         menu = self._MenuEditor__getMenu(item)
  521.         if menu == self.applications:
  522.             root = self.applications.visible_tree.root
  523.         elif menu == self.settings:
  524.             root = self.settings.visible_tree.root
  525.         
  526.         if item.get_type() == gmenu.TYPE_DIRECTORY:
  527.             return loop_for_menu(root, item)
  528.         
  529.         return True
  530.  
  531.     
  532.     def __getPath(self, menu, path = None):
  533.         if not path:
  534.             if self._MenuEditor__getMenu(menu) == self.applications:
  535.                 path = 'Applications'
  536.             else:
  537.                 path = 'Desktop'
  538.         
  539.         if menu.get_parent():
  540.             path = self._MenuEditor__getPath(menu.get_parent(), path)
  541.             path += '/'
  542.             path += menu.menu_id
  543.         
  544.         return path
  545.  
  546.     
  547.     def __getXmlMenu(self, path, element, dom):
  548.         if '/' in path:
  549.             (name, path) = path.split('/', 1)
  550.         else:
  551.             name = path
  552.             path = ''
  553.         found = None
  554.         for node in self._MenuEditor__getXmlNodesByName('Menu', element):
  555.             for child in self._MenuEditor__getXmlNodesByName('Name', node):
  556.                 if child.childNodes[0].nodeValue == name:
  557.                     if path:
  558.                         found = self._MenuEditor__getXmlMenu(path, node, dom)
  559.                     else:
  560.                         found = node
  561.                     break
  562.                     continue
  563.             
  564.             if found:
  565.                 break
  566.                 continue
  567.         
  568.         if not found:
  569.             node = self._MenuEditor__addXmlMenuElement(element, name, dom)
  570.             if path:
  571.                 found = self._MenuEditor__getXmlMenu(path, node, dom)
  572.             else:
  573.                 found = node
  574.         
  575.         return found
  576.  
  577.     
  578.     def __addXmlMenuElement(self, element, name, dom):
  579.         node = dom.createElement('Menu')
  580.         self._MenuEditor__addXmlTextElement(node, 'Name', name, dom)
  581.         return element.appendChild(node)
  582.  
  583.     
  584.     def __addXmlTextElement(self, element, name, text, dom):
  585.         node = dom.createElement(name)
  586.         text = dom.createTextNode(text)
  587.         node.appendChild(text)
  588.         return element.appendChild(node)
  589.  
  590.     
  591.     def __addXmlFilename(self, element, dom, filename, type = 'Include'):
  592.         for node in self._MenuEditor__getXmlNodesByName([
  593.             'Include',
  594.             'Exclude'], element):
  595.             if node.childNodes[0].nodeName == 'Filename' and node.childNodes[0].childNodes[0].nodeValue == filename:
  596.                 element.removeChild(node)
  597.                 continue
  598.         
  599.         node = dom.createElement(type)
  600.         node.appendChild(self._MenuEditor__addXmlTextElement(node, 'Filename', filename, dom))
  601.         return element.appendChild(node)
  602.  
  603.     
  604.     def __addDeleted(self, element, dom):
  605.         node = dom.createElement('Deleted')
  606.         return element.appendChild(node)
  607.  
  608.     
  609.     def __writeItem(self, item = None, icon = None, name = None, comment = None, command = None, use_term = None, no_display = None, startup_notify = None, hidden = None):
  610.         if item:
  611.             file_path = item.get_desktop_file_path()
  612.             file_id = item.get_desktop_file_id()
  613.             keyfile = util.DesktopParser(file_path)
  614.         elif item == None and name == None:
  615.             raise Exception('New menu items need a name')
  616.         else:
  617.             file_id = util.getUniqueFileId(name, '.desktop')
  618.             keyfile = util.DesktopParser()
  619.         if icon:
  620.             keyfile.set('Icon', icon)
  621.             keyfile.set('Icon', icon, self.locale)
  622.         
  623.         if name:
  624.             keyfile.set('Name', name)
  625.             keyfile.set('Name', name, self.locale)
  626.         
  627.         if comment:
  628.             keyfile.set('Comment', comment)
  629.             keyfile.set('Comment', comment, self.locale)
  630.         
  631.         if command:
  632.             keyfile.set('Exec', command)
  633.         
  634.         if use_term != None:
  635.             keyfile.set('Terminal', use_term)
  636.         
  637.         if no_display != None:
  638.             keyfile.set('NoDisplay', no_display)
  639.         
  640.         if startup_notify != None:
  641.             keyfile.set('StartupNotify', startup_notify)
  642.         
  643.         if hidden != None:
  644.             keyfile.set('Hidden', hidden)
  645.         
  646.         out_path = os.path.join(util.getUserItemPath(), file_id)
  647.         keyfile.write(open(out_path, 'w'))
  648.         return file_id
  649.  
  650.     
  651.     def __writeMenu(self, menu = None, icon = None, name = None, comment = None, no_display = None):
  652.         if menu:
  653.             file_id = os.path.split(menu.get_desktop_file_path())[1]
  654.             file_path = menu.get_desktop_file_path()
  655.             keyfile = util.DesktopParser(file_path)
  656.         elif menu == None and name == None:
  657.             raise Exception('New menus need a name')
  658.         else:
  659.             file_id = util.getUniqueFileId(name, '.directory')
  660.             keyfile = util.DesktopParser(file_type = 'Directory')
  661.         if icon:
  662.             keyfile.set('Icon', icon)
  663.         
  664.         if name:
  665.             keyfile.set('Name', name)
  666.             keyfile.set('Name', name, self.locale)
  667.         
  668.         if comment:
  669.             keyfile.set('Comment', comment)
  670.             keyfile.set('Comment', comment, self.locale)
  671.         
  672.         if no_display != None:
  673.             keyfile.set('NoDisplay', no_display)
  674.         
  675.         out_path = os.path.join(util.getUserDirectoryPath(), file_id)
  676.         keyfile.write(open(out_path, 'w'))
  677.         return file_id
  678.  
  679.     
  680.     def __getXmlNodesByName(self, name, element):
  681.         for child in element.childNodes:
  682.             if child.nodeType == xml.dom.Node.ELEMENT_NODE:
  683.                 if isinstance(name, str) and child.nodeName == name:
  684.                     yield child
  685.                 elif isinstance(name, list) or isinstance(name, tuple):
  686.                     if child.nodeName in name:
  687.                         yield child
  688.                     
  689.                 
  690.             isinstance(name, tuple)
  691.         
  692.  
  693.     
  694.     def __remove_whilespace_nodes(self, node):
  695.         remove_list = []
  696.         for child in node.childNodes:
  697.             if child.nodeType == xml.dom.minidom.Node.TEXT_NODE:
  698.                 child.data = child.data.strip()
  699.                 if not child.data.strip():
  700.                     remove_list.append(child)
  701.                 
  702.             child.data.strip()
  703.             if child.hasChildNodes():
  704.                 self._MenuEditor__remove_whilespace_nodes(child)
  705.                 continue
  706.         
  707.         for node in remove_list:
  708.             node.parentNode.removeChild(node)
  709.         
  710.  
  711.     
  712.     def __addXmlMove(self, element, old, new, dom):
  713.         if not self._MenuEditor__undoMoves(element, old, new, dom):
  714.             node = dom.createElement('Move')
  715.             node.appendChild(self._MenuEditor__addXmlTextElement(node, 'Old', old, dom))
  716.             node.appendChild(self._MenuEditor__addXmlTextElement(node, 'New', new, dom))
  717.             return element.insertBefore(node, element.firstChild)
  718.         
  719.  
  720.     
  721.     def __addXmlLayout(self, element, layout, dom):
  722.         for node in self._MenuEditor__getXmlNodesByName('Layout', element):
  723.             element.removeChild(node)
  724.         
  725.         node = dom.createElement('Layout')
  726.         for order in layout.order:
  727.             if order[0] == 'Separator':
  728.                 child = dom.createElement('Separator')
  729.                 node.appendChild(child)
  730.                 continue
  731.             if order[0] == 'Filename':
  732.                 child = self._MenuEditor__addXmlTextElement(node, 'Filename', order[1], dom)
  733.                 continue
  734.             if order[0] == 'Menuname':
  735.                 child = self._MenuEditor__addXmlTextElement(node, 'Menuname', order[1], dom)
  736.                 continue
  737.             if order[0] == 'Merge':
  738.                 child = dom.createElement('Merge')
  739.                 child.setAttribute('type', order[1])
  740.                 node.appendChild(child)
  741.                 continue
  742.         
  743.         return element.appendChild(node)
  744.  
  745.     
  746.     def __createLayout(self, items):
  747.         layout = Layout()
  748.         layout.order = []
  749.         layout.order.append([
  750.             'Merge',
  751.             'menus'])
  752.         for item in items:
  753.             if isinstance(item, tuple):
  754.                 if item[0] == 'Separator':
  755.                     layout.parseSeparator()
  756.                 elif item[0] == 'Menu':
  757.                     layout.parseMenuname(item[1])
  758.                 elif item[0] == 'Item':
  759.                     layout.parseFilename(item[1])
  760.                 
  761.             item[0] == 'Separator'
  762.             if item.get_type() == gmenu.TYPE_DIRECTORY:
  763.                 layout.parseMenuname(item.get_menu_id())
  764.                 continue
  765.             if item.get_type() == gmenu.TYPE_ENTRY:
  766.                 layout.parseFilename(item.get_desktop_file_id())
  767.                 continue
  768.             if item.get_type() == gmenu.TYPE_SEPARATOR:
  769.                 layout.parseSeparator()
  770.                 continue
  771.         
  772.         layout.order.append([
  773.             'Merge',
  774.             'files'])
  775.         return layout
  776.  
  777.     
  778.     def __addItem(self, parent, file_id, dom):
  779.         xml_parent = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent), dom, dom)
  780.         self._MenuEditor__addXmlFilename(xml_parent, dom, file_id, 'Include')
  781.  
  782.     
  783.     def __deleteItem(self, parent, file_id, dom, before = None, after = None):
  784.         xml_parent = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent), dom, dom)
  785.         self._MenuEditor__addXmlFilename(xml_parent, dom, file_id, 'Exclude')
  786.  
  787.     
  788.     def __positionItem(self, parent, item, before = None, after = None):
  789.         if not before and not after:
  790.             return None
  791.         
  792.         if after:
  793.             index = parent.contents.index(after) + 1
  794.         elif before:
  795.             index = parent.contents.index(before)
  796.         
  797.         contents = parent.contents
  798.         
  799.         try:
  800.             contents.remove(item)
  801.         except:
  802.             pass
  803.  
  804.         contents.insert(index, item)
  805.         layout = self._MenuEditor__createLayout(contents)
  806.         dom = self._MenuEditor__getMenu(parent).dom
  807.         menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent), dom, dom)
  808.         self._MenuEditor__addXmlLayout(menu_xml, layout, dom)
  809.  
  810.     
  811.     def __undoMoves(self, element, old, new, dom):
  812.         nodes = []
  813.         matches = []
  814.         original_old = old
  815.         final_old = old
  816.         for node in self._MenuEditor__getXmlNodesByName([
  817.             'Move'], element):
  818.             nodes.insert(0, node)
  819.         
  820.         for node in nodes:
  821.             xml_old = node.getElementsByTagName('Old')[0]
  822.             xml_new = node.getElementsByTagName('New')[0]
  823.             if xml_new.childNodes[0].nodeValue == old:
  824.                 matches.append(node)
  825.                 final_old = xml_old.childNodes[0].nodeValue
  826.                 continue
  827.         
  828.         for node in matches:
  829.             element.removeChild(node)
  830.         
  831.         if len(matches) > 0:
  832.             for node in nodes:
  833.                 xml_old = node.getElementsByTagName('Old')[0]
  834.                 xml_new = node.getElementsByTagName('New')[0]
  835.                 path = os.path.split(xml_new.childNodes[0].nodeValue)
  836.                 if path[0] == original_old:
  837.                     element.removeChild(node)
  838.                     for node in dom.getElementsByTagName('Menu'):
  839.                         name_node = node.getElementsByTagName('Name')[0]
  840.                         name = name_node.childNodes[0].nodeValue
  841.                         if name == os.path.split(new)[1]:
  842.                             root_path = dom.getElementsByTagName('Menu')[0].getElementsByTagName('Name')[0].childNodes[0].nodeValue
  843.                             xml_menu = self._MenuEditor__getXmlMenu(root_path + '/' + new, dom, dom)
  844.                             for app_dir in node.getElementsByTagName('AppDir'):
  845.                                 xml_menu.appendChild(app_dir)
  846.                             
  847.                             for dir_dir in node.getElementsByTagName('DirectoryDir'):
  848.                                 xml_menu.appendChild(dir_dir)
  849.                             
  850.                             parent = node.parentNode
  851.                             parent.removeChild(node)
  852.                             continue
  853.                     
  854.                     node = dom.createElement('Move')
  855.                     node.appendChild(self._MenuEditor__addXmlTextElement(node, 'Old', xml_old.childNodes[0].nodeValue, dom))
  856.                     node.appendChild(self._MenuEditor__addXmlTextElement(node, 'New', os.path.join(new, path[1]), dom))
  857.                     element.appendChild(node)
  858.                     continue
  859.             
  860.             if final_old == new:
  861.                 return True
  862.             
  863.             node = dom.createElement('Move')
  864.             node.appendChild(self._MenuEditor__addXmlTextElement(node, 'Old', final_old, dom))
  865.             node.appendChild(self._MenuEditor__addXmlTextElement(node, 'New', new, dom))
  866.             return element.appendChild(node)
  867.         
  868.  
  869.  
  870.  
  871. class Layout:
  872.     
  873.     def __init__(self, node = None):
  874.         self.order = []
  875.  
  876.     
  877.     def parseMenuname(self, value):
  878.         self.order.append([
  879.             'Menuname',
  880.             value])
  881.  
  882.     
  883.     def parseSeparator(self):
  884.         self.order.append([
  885.             'Separator'])
  886.  
  887.     
  888.     def parseFilename(self, value):
  889.         self.order.append([
  890.             'Filename',
  891.             value])
  892.  
  893.     
  894.     def parseMerge(self, merge_type = 'all'):
  895.         self.order.append([
  896.             'Merge',
  897.             merge_type])
  898.  
  899.  
  900.