Logo Search packages:      
Sourcecode: obmenu version File versions  Download package

obxml.py

#!/usr/bin/python
#
#  Openbox Menu Editor 1.0 beta
# 
#  Copyright 2005 Manuel Colmenero 
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


# ObMenu can be used as a module in python scripts, for example, to
# Generate dynamic menus (pipemenus)

import xml.dom.minidom

00027 class ObMenu:
      
      # Internal functions =============================================
      # (These mess with the xml tree)
            
      # given its ID, and its parent (or None for top-level)
      # returns the dom tree of the menu. Recursively.
      def _get_dom_menu(self, menu, parent=None):
            if not menu: return None
            if not parent: parent = self.dom.documentElement
            
            for item in parent.childNodes:
                  if item.nodeName == "menu" and item.hasChildNodes():
                        if item.attributes["id"].nodeValue == menu: return item
                        else:
                              b = self._get_dom_menu(menu, item)
                              if b: return b
            return None

      # given its ID, and its parent (or None for top-level)
      # returns the dom tree of the menu. Recursively.
      def _get_dom_ref(self, menu, parent):
            if not parent: parent = self.dom.documentElement
            for item in parent.childNodes:
                  if item.nodeName == "menu":
                        if not item.hasChildNodes():
                              if item.attributes["id"].nodeValue == menu: return item
                        else:
                              b = self._get_dom_menu(menu, item)
                              if b: return b
            return None
      
      # Get an item of 'menu', given its number (order)
      def _get_dom_item(self,menu,num):
            if not menu:
                  item = self.dom.documentElement
            else:
                  item = self._get_dom_menu(menu)
                  if not item: return None
            i = 0
            for it in item.childNodes:
                  if it.nodeType == 1:
                        if i == num: return it
                        i += 1
      
      # Insert a node in the xml tree
      def _put_dom_item(self, menu, nodo, pos=None):
            parent = self._get_dom_menu(menu)
            if not parent: parent = self.dom.documentElement
            
            if pos == None or pos > self._get_menu_len(menu):
                  parent.appendChild(nodo)
            elif pos >= 0:
                  ant = self._get_dom_item(menu, pos)
                  parent.insertBefore(nodo, ant)
      
      # Get the number of items of a menu
      def _get_menu_len(self,menu):
            if menu:
                  item = self._get_dom_menu(menu)
            else:
                  item = self.dom.documentElement
            i = 0
            for it in item.childNodes:
                  if it.nodeType == 1:
                        i += 1
            return i
      
      # Get "real" item number (counting with comments, text, etc in the xml)
      def _get_real_num(self,menu,num):
            if menu:
                  item = self._get_dom_menu(menu)
            else:
                  item = self.dom.documentElement
            i = 0
            n = 0
            for it in item.childNodes:
                  if it.nodeType == 1:
                        if i == num: return n
                        i += 1
                  n += 1
      
      # get the properties of an item from the xml, and returns them as a
      # dictionary.
      def _get_item_props(self,node):
            etiqueta = node.attributes["label"].nodeValue
            accion = ""
            param = ""
            for it in node.childNodes:
                  if it.nodeType == 1:
                        accion = it.attributes["name"].nodeValue
                        if accion.lower() == "execute":
                              for itm in it.childNodes:
                                    if itm.nodeType == 1 and itm.nodeName.lower() == "execute":
                                          for item in itm.childNodes:
                                                if item.nodeType == 3:
                                                      param = item.nodeValue.strip()
            return { "type": "item", "label": etiqueta, "action": accion, "execute": param }
      
      # get the properties of a menu from the xml, and returns them as a
      # dictionary.
      def _get_menu_props(self, node):
            lb = ""
            ex = ""
            act = ""
            mid = node.attributes["id"].nodeValue
            if node.hasAttribute("label"):
                  lb = node.attributes["label"].nodeValue
            else:
                  mnu = self._get_dom_menu(mid)
                  if mnu: lb = mnu.attributes["label"].nodeValue
                  else: lb = mid
            if not node.hasChildNodes():
                  if node.hasAttribute("execute"):
                        ex = node.attributes["execute"].nodeValue
                        act = "Pipemenu"
                  else:
                        act = "Link"
            if node.hasAttribute("execute"): ex = node.attributes["execute"].nodeValue
            return { "type": "menu", "label": lb, "action": act, "execute": ex, "id": mid }

      # Public functions ===================================================
      # Most of them are self-explanatory
                        
      def loadMenu(self, filename):
            fil = open(filename)
            self.dom = xml.dom.minidom.parseString(fil.read())
            fil.close()
      
      def newMenu(self):
            self.dom = xml.dom.minidom.parseString(
            "<?xml version=\"1.0\" ?><openbox_menu></openbox_menu>")
            #self.dom._set_async(False)

      def newPipe(self):
            self.dom = xml.dom.minidom.parseString(
            "<?xml version=\"1.0\" ?><openbox_pipe_menu></openbox_pipe_menu>")
      
      def saveMenu(self, filename):
            output = open(filename, "w")
            for line in self.dom.toprettyxml("\t","\n","utf-8").splitlines():
                  if line.strip() != "":
                        output.write("%s\n" %(line))
            output.close()
      
      def printXml(self):
            for line in self.dom.toprettyxml("\t","\n","utf-8").splitlines():
                  if line.strip() != "":
                        print line
      
      def getXml(self):
            res = ""
            for line in self.dom.toprettyxml("\t","\n","utf-8").splitlines():
                  if line.strip() != "":
                        res = res + "%s\n" % (line)
            return res
                        
      def removeItem(self,menu, num):
            if menu:
                  dom_mnu = self._get_dom_menu(menu)
            else:
                  dom_mnu = self.dom.documentElement
            item = self._get_dom_item(menu,num)
            dom_mnu.removeChild(item)
            item.unlink()
      
      def removeMenu(self,menu):
            dom_mnu = self._get_dom_menu(menu)
            if not dom_mnu.parentNode:
                  self.dom.documentElement.removeChild(dom_mnu)
            else:
                  dom_mnu.parentNode.removeChild(dom_mnu)
            dom_mnu.unlink()
      
      def createSep(self, menu, pos=None):            
            nodo = self.dom.createElement("separator")
            self._put_dom_item(menu, nodo, pos)
                  
      def createItem(self, menu, label, action, execute, pos=None):
            nodo = self.dom.createElement("item")
            nodo.attributes["label"] = label
            accion = self.dom.createElement("action")
            accion.attributes["name"] = "Execute"
            exe = self.dom.createElement("execute")
            txt = self.dom.createTextNode("")
            txt.nodeValue = execute
            exe.appendChild(txt)
            accion.appendChild(exe)
            nodo.appendChild(accion)
            self._put_dom_item(menu, nodo, pos)
      
      def createLink(self, menu, mid, pos=None):
            nodo = self.dom.createElement("menu")
            nodo.attributes["id"] = mid
            self._put_dom_item(menu, nodo, pos)

      def createPipe(self, menu, mid, label, execute, pos=None):
            nodo = self.dom.createElement("menu")
            nodo.attributes["id"] = mid
            nodo.attributes["label"] = label
            nodo.attributes["execute"] = execute
            
            self._put_dom_item(menu, nodo, pos)
            
      def createMenu(self, menu, label, mid, pos=None):
            nodo = self.dom.createElement("menu")
            nodo.attributes["label"] = label
            nodo.attributes["id"] = mid
            txt = self.dom.createTextNode("")
            txt.nodeValue = "\n"
            nodo.appendChild(txt)
            self._put_dom_item(menu, nodo, pos)
            
      def interchange(self, menu, n1, n2):
            if not menu:
                  dom_mnu = self.dom.documentElement
            else:
                  dom_mnu = self._get_dom_menu(menu)
            i1 = self._get_real_num(menu, n1)
            i2 = self._get_real_num(menu, n2)
            uno = dom_mnu.childNodes[i1]
            dom_mnu.childNodes[i1] = dom_mnu.childNodes[i2]
            dom_mnu.childNodes[i2] = uno
      
      def setItemProps(self, menu, n, label, action, exe):
            itm = self._get_dom_item(menu,n)
            itm.attributes["label"].nodeValue = label
            for it in itm.childNodes:
                  if it.nodeType == 1:
                        it.attributes["name"].nodeValue = action
                        if action == "Execute":
                              if not it.childNodes:
                                    elm = xml.dom.minidom.Element("execute")
                                    txt = xml.dom.minidom.Text()
                                    txt.nodeValue = exe
                                    elm.appendChild(txt)
                                    it.appendChild(elm)
                              else:
                                    for i in it.childNodes:
                                          if i.nodeType == 1 and i.nodeName == "execute":
                                                for item in i.childNodes:
                                                      if item.nodeType == 3:
                                                            item.nodeValue = exe
                        else:
                              for item in it.childNodes:
                                    it.removeChild(item)
      
      def setMenuLabel(self, menu, label):
            mnu = self._get_dom_menu(menu)
            if mnu: mnu.attributes["label"].nodeValue = label
      
      def getMenuLabel(self,menu):
            mnu = self._get_dom_menu(menu)
            if mnu: return mnu.attributes["label"].nodeValue

      def setRefLabel(self, parent, mid, label):
            prnt = self._get_dom_menu(parent)
            if prnt: mnu = self._get_dom_ref(mid, prnt)
            if mnu: mnu.setAttribute("label", label)

      def setRefId(self, parent, mid, new_id):
            prnt = self._get_dom_menu(parent)
            if prnt: mnu = self._get_dom_ref(mid, prnt)
            if mnu: mnu.setAttribute("id", new_id)
      
      def setMenuExecute(self, parent, mid, execute):
            prnt = self._get_dom_menu(parent)
            if prnt: mnu = self._get_dom_ref(mid, prnt)
            if mnu: mnu.setAttribute("execute", execute)
      
      # Return just an item, given its parent menu an its number
      def getItem(self,menu,num):
            mnu = self._get_dom_menu(menu)
            if not mnu: return
            n = 0
            for i in mnu.childNodes:
                  if i.nodeType == 1:
                        if n == num:
                              if i.nodeName == "menu":
                                    return self._get_menu_props(i)
                              elif i.nodeName == "separator":
                                    return { "type": "separator" }
                              elif i.nodeName == "item":
                                    return self.get_item_props(i)
                        n += 1
      
      # Is menu? Returns True if it's an existing ID
      def isMenu(self,menu):
            dom = self._get_dom_menu(menu)
            if dom:
                  return True
            else:
                  return False
            
      
      # Returns a whole menu, as a list of dictionaries.
      # Each dictionary has the items properties.
      def getMenu(self,menu):
            lst = []
            if menu:
                  mnu = self._get_dom_menu(menu)
                  if not mnu: return
            else:
                  mnu = self.dom.documentElement
            for i in mnu.childNodes:
                  if i.nodeType == 1:
                        if i.nodeName == "menu":
                              d = self._get_menu_props(i)
                              d["parent"] = menu
                              lst.append(d)
                        elif i.nodeName == "separator":
                              lst.append({"type": "separator", "parent": menu})
                        elif i.nodeName == "item":
                              d = self._get_item_props(i)
                              d["parent"] = menu            
                              lst.append(d)
            return lst

      # replace all old_id's in file with new_id's
      # parent shuld start with None      
      def replaceId(self, old_id, new_id, parent=None):
            if not parent: parent = self.dom.documentElement
            for item in parent.childNodes:
                  if item.nodeName == "menu":
                        if item.attributes["id"].nodeValue == old_id:
                              item.setAttribute("id", new_id)
                        elif item.hasChildNodes():
                              self.replaceId(old_id, new_id, item)

if __name__ == "__main__":
      print "This is a module. Use obmenu instead."
      exit(0)

Generated by  Doxygen 1.6.0   Back to index