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 / GMenuSimpleEditor / menufilewriter.py < prev    next >
Encoding:
Python Source  |  2006-08-30  |  6.4 KB  |  195 lines

  1. #!/usr/bin/env python
  2.  
  3. #
  4. # Copyright (C) 2005 Red Hat, Inc.
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, write to the Free Software
  18. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. #
  20.  
  21. import os
  22. import errno
  23. import pwd
  24. import gobject
  25. import menutreemodel
  26.  
  27. DTD_DECLARATION = '<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"\n' \
  28.                   ' "http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd">\n\n'
  29.  
  30. class MenuFileWriterError (Exception):
  31.     pass
  32.  
  33. def get_home_dir ():
  34.     try:
  35.         pw = pwd.getpwuid (os.getuid ())
  36.         if pw.pw_dir:
  37.             return pw.pw_dir
  38.     except KeyError:
  39.         pass
  40.  
  41.     if os.environ.has_key ("HOME"):
  42.         return os.environ["HOME"]
  43.     else:
  44.         raise MenuFileWriterError (_("Cannot find home directory: not set in /etc/passwd and no value for $HOME in environment"))
  45.  
  46. def get_user_menu_file_path (menu_file):
  47.     config_dir = None
  48.     if os.environ.has_key ("XDG_CONFIG_HOME"):
  49.         config_dir = os.environ["XDG_CONFIG_HOME"]
  50.     if not config_dir:
  51.         config_dir = os.path.join (get_home_dir (), ".config")
  52.     
  53.     return os.path.join (config_dir, "menus", menu_file)
  54.  
  55. def write_file (filename, contents):
  56.     dir = os.path.dirname (filename)
  57.     try:
  58.         os.makedirs (dir)
  59.     except os.error, (err, str):
  60.         if err != errno.EEXIST:
  61.             raise
  62.     
  63.     temp = filename + ".new"
  64.     try:
  65.         f = file (temp, "w")
  66.     except:
  67.         temp = None
  68.         f = file (filename, "w")
  69.     
  70.     try:
  71.         f.write (contents)
  72.         f.close ()
  73.     except:
  74.         if temp != None:
  75.             os.remove (temp)
  76.         raise
  77.  
  78.     if temp != None:
  79.         os.rename (temp, filename)
  80.  
  81. class MenuFileWriter:
  82.     def __init__ (self, menu_tree_model):
  83.         self.model = menu_tree_model
  84.  
  85.         self.sync_idle_handlers = {}
  86.  
  87.     def __del__ (self):
  88.         for (id, iter) in self.sync_idle_handlers:
  89.             gobject.source_remove (id)
  90.  
  91.     def __append_menu (self, contents, indent, iter, system_menu_file = None):
  92.         has_changes = False
  93.         orig_contents = contents
  94.         
  95.         contents += indent + "<Menu>\n"
  96.         contents += indent + "  <Name>%s</Name>\n" % self.model[iter][self.model.COLUMN_ID]
  97.  
  98.         if system_menu_file:
  99.             contents += indent + '  <MergeFile type="parent">%s</MergeFile>\n' % system_menu_file
  100.  
  101.         includes = []
  102.         excludes = []
  103.  
  104.         child_iter = self.model.iter_children (iter)
  105.         while child_iter:
  106.             if self.model[child_iter][self.model.COLUMN_IS_ENTRY]:
  107.                 desktop_file_id = self.model[child_iter][self.model.COLUMN_ID]
  108.                 system_visible  = self.model[child_iter][self.model.COLUMN_SYSTEM_VISIBLE]
  109.                 user_visible    = self.model[child_iter][self.model.COLUMN_USER_VISIBLE]
  110.  
  111.                 if not system_visible and user_visible:
  112.                     includes.append (desktop_file_id)
  113.                 elif system_visible and not user_visible:
  114.                     excludes.append (desktop_file_id)
  115.  
  116.             child_iter = self.model.iter_next (child_iter)
  117.  
  118.         if len (includes) > 0:
  119.             contents += indent + "  <Include>\n"
  120.             for desktop_file_id in includes:
  121.                 contents += indent + "    <Filename>%s</Filename>\n" % desktop_file_id
  122.             contents += indent + "  </Include>\n"
  123.             has_changes = True
  124.         
  125.         if len (excludes) > 0:
  126.             contents += indent + "  <Exclude>\n"
  127.             for desktop_file_id in excludes:
  128.                 contents += indent + "    <Filename>%s</Filename>\n" % desktop_file_id
  129.             contents += indent + "  </Exclude>\n"
  130.             has_changes = True
  131.         
  132.         child_iter = self.model.iter_children (iter)
  133.         while child_iter:
  134.             if not self.model[child_iter][self.model.COLUMN_IS_ENTRY]:
  135.                 (contents, subdir_has_changes) = self.__append_menu (contents,
  136.                                                                      indent + "  ",
  137.                                                                      child_iter)
  138.                 if not has_changes:
  139.                     has_changes = subdir_has_changes
  140.  
  141.             child_iter = self.model.iter_next (child_iter)
  142.  
  143.         if has_changes:
  144.             return (contents + indent + "</Menu>\n", True)
  145.         else:
  146.             return (orig_contents, False)
  147.  
  148.     def sync (self, iter):
  149.         menu_file = self.model[iter][self.model.COLUMN_MENU_FILE]
  150.         system_menu_file = menutreemodel.lookup_system_menu_file (menu_file)
  151.         
  152.         (contents, has_changes) = self.__append_menu (DTD_DECLARATION,
  153.                                                       "",
  154.                                                       iter,
  155.                                                       system_menu_file)
  156.  
  157.         if not has_changes:
  158.             try:
  159.                 os.remove (get_user_menu_file_path (menu_file))
  160.             except:
  161.                 pass
  162.             return
  163.             
  164.         write_file (get_user_menu_file_path (menu_file), contents)
  165.  
  166.     def __sync_idle_handler_func (self, iter):
  167.         self.sync (iter)
  168.         del self.sync_idle_handlers[iter]
  169.         return False
  170.  
  171.     def queue_sync (self, iter):
  172.         def find_menu_file_parent (model, iter):
  173.             if model[iter][model.COLUMN_MENU_FILE]:
  174.                 return iter
  175.             
  176.             parent_iter = model.iter_parent (iter)
  177.             if not parent_iter:
  178.                 return None
  179.  
  180.             return find_menu_file_parent (model, parent_iter)
  181.  
  182.         menu_file_iter = find_menu_file_parent (self.model, iter)
  183.         if not menu_file_iter:
  184.             return
  185.  
  186.         menu_file_path = self.model.get_string_from_iter (menu_file_iter)
  187.         for iter in self.sync_idle_handlers:
  188.             path = self.model.get_string_from_iter (iter)
  189.             if path == menu_file_path:
  190.                 return
  191.  
  192.         id = gobject.idle_add (self.__sync_idle_handler_func, menu_file_iter)
  193.  
  194.         self.sync_idle_handlers[menu_file_iter] = id
  195.