[alacarte] port to latest gmenu / introspection



commit ce1ee2b350189692a7a89a52d8b76047d5ae7df8
Author: Ray Strode <rstrode redhat com>
Date:   Tue Nov 29 17:47:07 2011 -0500

    port to latest gmenu / introspection
    
    https://bugzilla.gnome.org/show_bug.cgi?id=626220

 Alacarte/MainWindow.py |   91 +++++++++++++-----------
 Alacarte/MenuEditor.py |  181 +++++++++++++++++++++++++++++++++---------------
 Alacarte/util.py       |   35 ++++-----
 configure.ac           |    2 +-
 4 files changed, 191 insertions(+), 118 deletions(-)
---
diff --git a/Alacarte/MainWindow.py b/Alacarte/MainWindow.py
index 60c318a..b5fc35b 100644
--- a/Alacarte/MainWindow.py
+++ b/Alacarte/MainWindow.py
@@ -17,8 +17,7 @@
 #   License along with this library; if not, write to the Free Software
 #   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-from gi.repository import Gtk, GObject, Gio, GdkPixbuf, Gdk
-import gmenu
+from gi.repository import Gtk, GObject, Gio, GdkPixbuf, Gdk, GMenu
 import cgi, os
 import gettext
 import subprocess
@@ -32,6 +31,8 @@ except:
 _ = gettext.gettext
 from Alacarte.MenuEditor import MenuEditor
 from Alacarte import util
+import sys
+from traceback import print_stack
 
 class MainWindow:
 	timer = None
@@ -72,17 +73,22 @@ class MainWindow:
 
 	def run(self):
 		self.loadMenus()
-		self.editor.applications.tree.add_monitor(self.menuChanged, None)
+		self.editor.applications.tree.connect("changed", self.menuChanged)
 		self.tree.get_object('mainwindow').show_all()
 		Gtk.main()
 
 	def menuChanged(self, *a):
+		print >> sys.stderr, "changed!\n"
 		if self.timer:
 			GObject.source_remove(self.timer)
 			self.timer = None
 		self.timer = GObject.timeout_add(3, self.loadUpdates)
 
 	def loadUpdates(self):
+		print >> sys.stderr, "%d\n" % self.editor.applications.tree.disconnect_by_func(self.menuChanged)
+		self.editor.reloadMenus()
+		self.editor.applications.tree.connect("changed", self.menuChanged)
+
 		if not self.allow_update:
 			return False
 		menu_tree = self.tree.get_object('menu_tree')
@@ -93,13 +99,15 @@ class MainWindow:
 		item_id, separator_path = None, None
 		if iter:
 			update_items = True
-			update_type = items[iter][3].get_type()
-			if items[iter][3].get_type() == gmenu.TYPE_ENTRY:
+			if isinstance(items[iter][3], GMenu.TreeEntry):
 				item_id = items[iter][3].get_desktop_file_id()
-			if items[iter][3].get_type() == gmenu.TYPE_DIRECTORY:
+				update_type = GMenu.TreeItemType.ENTRY
+			elif isinstance(items[iter][3], GMenu.TreeDirectory):
 				item_id = os.path.split(items[iter][3].get_desktop_file_path())[1]
-			elif items[iter][3].get_type() == gmenu.TYPE_SEPARATOR:
+				update_type = GMenu.TreeItemType.DIRECTORY
+			elif isinstance(items[iter][3], GMenu.Tree.Separator):
 				item_id = items.get_path(iter)
+				update_type = GMenu.TreeItemType.SEPARATOR
 		menus, iter = menu_tree.get_selection().get_selected()
 		update_menus = False
 		menu_id = None
@@ -121,13 +129,13 @@ class MainWindow:
 			i = 0
 			for item in item_tree.get_model():
 				found = False
-				if update_type != gmenu.TYPE_SEPARATOR:
-					if item[3].get_type() == gmenu.TYPE_ENTRY and item[3].get_desktop_file_id() == item_id:
+				if update_type != GMenu.TreeItemType.SEPARATOR:
+					if isinstance (item[3], GMenu.TreeEntry) and item[3].get_desktop_file_id() == item_id:
 						found = True
-					if item[3].get_type() == gmenu.TYPE_DIRECTORY and item[3].get_desktop_file_path() and update_type == gmenu.TYPE_DIRECTORY:
+					if isinstance (item[3], GMenu.TreeDirectory) and item[3].get_desktop_file_path() and update_type == GMenu.TreeItemType.DIRECTORY:
 						if os.path.split(item[3].get_desktop_file_path())[1] == item_id:
 							found = True
-				if item[3].get_type() == gmenu.TYPE_SEPARATOR:
+				if isinstance(item[3], GMenu.TreeSeparator):
 					if not isinstance(item_id, tuple):
 						#we may not skip the increment via "continue"
 						i += 1
@@ -202,7 +210,7 @@ class MainWindow:
 		items.enable_model_drag_dest(self.dnd_items, Gdk.DragAction.PRIVATE)
 
 	def _cell_data_toggle_func(self, tree_column, renderer, model, treeiter, data=None):
-		if model[treeiter][3].get_type() == gmenu.TYPE_SEPARATOR:
+		if isinstance(model[treeiter][3], GMenu.TreeSeparator):
 			renderer.set_property('visible', False)
 		else:
 			renderer.set_property('visible', True)
@@ -242,14 +250,15 @@ class MainWindow:
 		self.item_store.clear()
 		for item, show in self.editor.getItems(menu):
 			menu_icon = None
-			if item.get_type() == gmenu.TYPE_SEPARATOR:
+			if isinstance(item, GMenu.TreeSeparator):
 				name = '---'
 				icon = None
-			elif item.get_type() == gmenu.TYPE_ENTRY:
+			elif isinstance(item, GMenu.TreeEntry):
+				app_info = item.get_app_info()
 				if show:
-					name = cgi.escape(item.get_display_name())
+					name = cgi.escape(app_info.get_display_name())
 				else:
-					name = '<small><i>' + cgi.escape(item.get_display_name()) + '</i></small>'
+					name = '<small><i>' + cgi.escape(app_info.get_display_name()) + '</i></small>'
 				icon = util.getIcon(item)
 			else:
 				if show:
@@ -297,7 +306,7 @@ class MainWindow:
 			parent = menus[iter][2]
 		file_path = os.path.join(util.getUserDirectoryPath(), util.getUniqueFileId('alacarte-made', '.directory'))
 		process = subprocess.Popen(['gnome-desktop-item-edit', file_path], env=os.environ)
-		GObject.timeout_add(100, self.waitForNewMenuProcess, process, parent.menu_id, file_path)
+		GObject.timeout_add(100, self.waitForNewMenuProcess, process, parent.get_menu_id(), file_path)
 
 	def on_new_item_button_clicked(self, button):
 		menu_tree = self.tree.get_object('menu_tree')
@@ -310,7 +319,7 @@ class MainWindow:
 			parent = menus[iter][2]
 		file_path = os.path.join(util.getUserItemPath(), util.getUniqueFileId('alacarte-made', '.desktop'))
 		process = subprocess.Popen(['gnome-desktop-item-edit', file_path], env=os.environ)
-		GObject.timeout_add(100, self.waitForNewItemProcess, process, parent.menu_id, file_path)
+		GObject.timeout_add(100, self.waitForNewItemProcess, process, parent.get_menu_id(), file_path)
 
 	def on_new_separator_button_clicked(self, button):
 		item_tree = self.tree.get_object('item_tree')
@@ -330,11 +339,11 @@ class MainWindow:
 		if not iter:
 			return
 		item = items[iter][3]
-		if item.get_type() == gmenu.TYPE_ENTRY:
+		if isinstance(item, GMenu.TreeEntry):
 			self.editor.deleteItem(item)
-		elif item.get_type() == gmenu.TYPE_DIRECTORY:
+		elif isinstance(item, GMenu.TreeDirectory):
 			self.editor.deleteMenu(item)
-		elif item.get_type() == gmenu.TYPE_SEPARATOR:
+		elif isinstance(item, GMenu.TreeSeparator):
 			self.editor.deleteSeparator(item)
 
 	def on_edit_revert_to_original_activate(self, menu):
@@ -343,9 +352,9 @@ class MainWindow:
 		if not iter:
 			return
 		item = items[iter][3]
-		if item.get_type() == gmenu.TYPE_ENTRY:
+		if isinstance(item, GMenu.TreeEntry):
 			self.editor.revertItem(item)
-		elif item.get_type() == gmenu.TYPE_DIRECTORY:
+		elif isinstance(item, GMenu.TreeDirectory):
 			self.editor.revertMenu(item)
 
 	def on_edit_properties_activate(self, menu):
@@ -354,13 +363,13 @@ class MainWindow:
 		if not iter:
 			return
 		item = items[iter][3]
-		if item.get_type() not in (gmenu.TYPE_ENTRY, gmenu.TYPE_DIRECTORY):
+		if not isinstance(item, GMenu.TreeEntry) and not isinstance(item, GMenu.TreeDirectory):
 			return
 
-		if item.get_type() == gmenu.TYPE_ENTRY:
+		if isinstance(item, GMenu.TreeEntry):
 			file_path = os.path.join(util.getUserItemPath(), item.get_desktop_file_id())
 			file_type = 'Item'
-		elif item.get_type() == gmenu.TYPE_DIRECTORY:
+		elif isinstance(item, GMenu.TreeDirectory):
 			if item.get_desktop_file_path() == None:
 				file_path = util.getUniqueFileId('alacarte-made', '.directory')
 				parser = util.DesktopParser(file_path, 'Directory')
@@ -419,12 +428,12 @@ class MainWindow:
 				item = self.drag_data
 				new_parent = menus[path][2]
 				treeview.get_selection().select_path(path)
-				if item.get_type() == gmenu.TYPE_ENTRY:
+				if isinstance(item, GMenu.TreeEntry):
 					self.editor.copyItem(item, new_parent)
-				elif item.get_type() == gmenu.TYPE_DIRECTORY:
+				elif isinstance(item, GMenu.TreeDirectory):
 					if self.editor.moveMenu(item, new_parent) == False:
 						self.loadUpdates()
-				elif item.get_type() == gmenu.TYPE_SEPARATOR:
+				elif isinstance(item, GMenu.TreeSeparator):
 					self.editor.moveSeparator(item, new_parent)
 				else:
 					context.finish(False, False, etime) 
@@ -433,7 +442,7 @@ class MainWindow:
 
 	def on_item_tree_show_toggled(self, cell, path):
 		item = self.item_store[path][3]
-		if item.get_type() == gmenu.TYPE_SEPARATOR:
+		if isinstance(item, GMenu.TreeSeparator):
 			return
 		if self.item_store[path][0]:
 			self.editor.setVisible(item, False)
@@ -453,7 +462,7 @@ class MainWindow:
 			self.tree.get_object('edit_revert_to_original').set_sensitive(True)
 		else:
 			self.tree.get_object('edit_revert_to_original').set_sensitive(False)
-		if not item.get_type() == gmenu.TYPE_SEPARATOR:
+		if not isinstance(item, GMenu.TreeSeparator):
 			self.tree.get_object('edit_properties').set_sensitive(True)
 			self.tree.get_object('properties_button').set_sensitive(True)
 		else:
@@ -519,7 +528,7 @@ class MainWindow:
 				path, position = drop_info
 				target = items[path][3]
 				# move the item to the directory, if the item was dropped into it
-				if (target.get_type() == gmenu.TYPE_DIRECTORY) and (position in types_into):
+				if isinstance(target, GMenu.TreeDirectory) and (position in types_into):
 					# append the selected item to the choosen menu
 					destination = target
 				elif position in types_before:
@@ -532,12 +541,12 @@ class MainWindow:
 			else:
 				path = (len(items) - 1,)
 				after = items[path][3]
-			if item.get_type() == gmenu.TYPE_ENTRY:
+			if isinstance(item, GMenu.TreeEntry):
 				self.editor.moveItem(item, destination, before, after)
-			elif item.get_type() == gmenu.TYPE_DIRECTORY:
+			elif isinstance(item, GMenu.TreeDirectory):
 				if self.editor.moveMenu(item, destination, before, after) == False:
 					self.loadUpdates()
-			elif item.get_type() == gmenu.TYPE_SEPARATOR:
+			elif isinstance(item, GMenu.TreeSeparator):
 				self.editor.moveSeparator(item, destination, before, after)
 			context.finish(True, True, etime)
 		elif selection.target == 'text/plain':
@@ -591,11 +600,11 @@ class MainWindow:
 			return
 		item = items[path][3]
 		before = items[(path.get_indices()[0] - 1,)][3]
-		if item.get_type() == gmenu.TYPE_ENTRY:
+		if isinstance(item, GMenu.TreeEntry):
 			self.editor.moveItem(item, item.get_parent(), before=before)
-		elif item.get_type() == gmenu.TYPE_DIRECTORY:
+		elif isinstance(item, GMenu.TreeDirectory):
 			self.editor.moveMenu(item, item.get_parent(), before=before)
-		elif item.get_type() == gmenu.TYPE_SEPARATOR:
+		elif isinstance(item, GMenu.TreeSeparator):
 			self.editor.moveSeparator(item, item.get_parent(), before=before)
 
 	def on_move_down_button_clicked(self, button):
@@ -609,11 +618,11 @@ class MainWindow:
 			return
 		item = items[path][3]
 		after = items[path][3]
-		if item.get_type() == gmenu.TYPE_ENTRY:
+		if isinstance(item, GMenu.TreeEntry):
 			self.editor.moveItem(item, item.get_parent(), after=after)
-		elif item.get_type() == gmenu.TYPE_DIRECTORY:
+		elif isinstance(item, GMenu.TreeDirectory):
 			self.editor.moveMenu(item, item.get_parent(), after=after)
-		elif item.get_type() == gmenu.TYPE_SEPARATOR:
+		elif isinstance(item, GMenu.TreeSeparator):
 			self.editor.moveSeparator(item, item.get_parent(), after=after)
 
 	def on_mainwindow_undo(self, accelgroup, window, keyval, modifier):
diff --git a/Alacarte/MenuEditor.py b/Alacarte/MenuEditor.py
index 8914039..3ca8a0e 100644
--- a/Alacarte/MenuEditor.py
+++ b/Alacarte/MenuEditor.py
@@ -16,8 +16,8 @@
 #   License along with this library; if not, write to the Free Software
 #   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-import os, re, xml.dom.minidom, locale
-import gmenu
+import os, sys, re, xml.dom.minidom, locale
+from gi.repository import GMenu
 from Alacarte import util
 
 class Menu:
@@ -35,20 +35,31 @@ class MenuEditor:
 		self.locale = locale.getdefaultlocale()[0]
 		self.__loadMenus()
 
-	def __loadMenus(self):
+	def reloadMenus(self):
 		self.applications = Menu()
-		self.applications.tree = gmenu.lookup_tree('applications.menu', gmenu.FLAGS_SHOW_EMPTY|gmenu.FLAGS_INCLUDE_EXCLUDED|gmenu.FLAGS_INCLUDE_NODISPLAY|gmenu.FLAGS_SHOW_ALL_SEPARATORS)
-		self.applications.visible_tree = gmenu.lookup_tree('applications.menu')
-		self.applications.tree.sort_key = gmenu.SORT_DISPLAY_NAME
-		self.applications.visible_tree.sort_key = gmenu.SORT_DISPLAY_NAME
-		self.applications.path = os.path.join(util.getUserMenuPath(), self.applications.tree.get_menu_file())
+		self.applications.tree = GMenu.Tree.new('applications.menu', GMenu.TreeFlags.SHOW_EMPTY|GMenu.TreeFlags.INCLUDE_EXCLUDED|GMenu.TreeFlags.INCLUDE_NODISPLAY|GMenu.TreeFlags.SHOW_ALL_SEPARATORS|GMenu.TreeFlags.SORT_DISPLAY_NAME)
+		if not self.applications.tree.load_sync():
+			self.applications = None
+			return
+		self.applications.visible_tree = GMenu.Tree.new('applications.menu', GMenu.TreeFlags.SORT_DISPLAY_NAME)
+		if not self.applications.visible_tree.load_sync():
+			self.applications = None
+			return
+		self.applications.path = os.path.join(util.getUserMenuPath(), self.applications.tree.props.menu_basename)
 		if not os.path.isfile(self.applications.path):
 			self.applications.dom = xml.dom.minidom.parseString(util.getUserMenuXml(self.applications.tree))
 		else:
 			self.applications.dom = xml.dom.minidom.parse(self.applications.path)
 		self.__remove_whilespace_nodes(self.applications.dom)
 
+	def __menuChanged(self, *a):
+		print >> sys.stderr, "changed!\n"
+		self.applications.visible_tree.load_sync()
+
+	def __loadMenus(self):
+		self.reloadMenus();
 		self.save(True)
+		self.applications.visible_tree.connect("changed", self.__menuChanged)
 
 	def save(self, from_loading=False):
 		for menu in ('applications',):
@@ -75,8 +86,8 @@ class MenuEditor:
 	def revert(self):
 		for name in ('applications',):
 			menu = getattr(self, name)
-			self.revertTree(menu.tree.root)
-			path = os.path.join(util.getUserMenuPath(), menu.tree.get_menu_file())
+			self.revertTree(menu.tree.get_root_directory())
+			path = os.path.join(util.getUserMenuPath(), os.path.basename(menu.tree.get_canonical_menu_path()))
 			try:
 				os.unlink(path)
 			except OSError:
@@ -92,11 +103,16 @@ class MenuEditor:
 		self.save()
 
 	def revertTree(self, menu):
-		for child in menu.get_contents():
-			if child.get_type() == gmenu.TYPE_DIRECTORY:
-				self.revertTree(child)
-			elif child.get_type() == gmenu.TYPE_ENTRY:
-				self.revertItem(child)
+		item_iter = menu.iter()
+		item_type = item_iter.next()
+		while item_type != GMenu.TreeItemType.INVALID:
+			if item_type == GMenu.TreeItemType.DIRECTORY:
+				item = item_iter.get_directory();
+				self.revertTree(item)
+			elif item_type == GMenu.TreeItemType.ENTRY:
+				item = item_iter.get_entry();
+				self.revertItem(item)
+			item_type = item_iter.next()
 		self.revertMenu(menu)
 
 	def undo(self):
@@ -149,28 +165,63 @@ class MenuEditor:
 
 	def getMenus(self, parent=None):
 		if parent == None:
-			yield self.applications.tree.root
+			yield self.applications.tree.get_root_directory()
 		else:
-			for menu in parent.get_contents():
-				if menu.get_type() == gmenu.TYPE_DIRECTORY:
-					yield (menu, self.__isVisible(menu))
+			item_iter = parent.iter()
+			item_type = item_iter.next()
+			while item_type != GMenu.TreeItemType.INVALID:
+				if item_type == GMenu.TreeItemType.DIRECTORY:
+					item = item_iter.get_directory()
+					yield (item, self.__isVisible(item))
+				item_type = item_iter.next()
+
+	def getContents(self, item):
+		contents = []
+		item_iter = item.iter()
+		item_type = item_iter.next()
+
+		while item_type != GMenu.TreeItemType.INVALID:
+			if item_type == GMenu.TreeItemType.DIRECTORY:
+			    item = item_iter.get_directory()
+			elif item_type == GMenu.TreeItemType.ENTRY:
+			    item = item_iter.get_entry()
+			elif item_type == GMenu.TreeItemType.HEADER:
+			    item = item_iter.get_header()
+			elif item_type == GMenu.TreeItemType.ALIAS:
+			    item = item_iter.get_alias()
+			if item:
+			    contents.append(item)
+			item_type = item_iter.next()
+		return contents;
 
 	def getItems(self, menu):
-		for item in menu.get_contents():
-			if item.get_type() == gmenu.TYPE_SEPARATOR:
+		item_iter = menu.iter()
+		item_type = item_iter.next()
+		while item_type != GMenu.TreeItemType.INVALID:
+			if item_type == GMenu.TreeItemType.SEPARATOR:
+				item = item_iter.get_separator()
 				yield (item, True)
 			else:
-				if item.get_type() == gmenu.TYPE_ENTRY and item.get_desktop_file_id()[-19:] == '-usercustom.desktop':
-					continue
+				if item_type == GMenu.TreeItemType.ENTRY:
+					item = item_iter.get_entry()
+					if item.get_desktop_file_id()[-19:] == '-usercustom.desktop':
+					    continue
+				elif item_type == GMenu.TreeItemType.DIRECTORY:
+					item = item_iter.get_directory()
+				elif item_type == GMenu.TreeItemType.HEADER:
+					item = item_iter.get_header()
+				elif item_type == GMenu.TreeItemType.ALIAS:
+					item = item_iter.get_alias()
 				yield (item, self.__isVisible(item))
+			item_type = item_iter.next()
 
 	def canRevert(self, item):
-		if item.get_type() == gmenu.TYPE_ENTRY:
+		if isinstance(item, GMenu.TreeEntry):
 			if util.getItemPath(item.get_desktop_file_id()):
 				path = util.getUserItemPath()
 				if os.path.isfile(os.path.join(path, item.get_desktop_file_id())):
 					return True
-		elif item.get_type() == gmenu.TYPE_DIRECTORY:
+		elif isinstance(item, GMenu.TreeDirectory):
 			if item.get_desktop_file_path():
 				file_id = os.path.split(item.get_desktop_file_path())[1]
 			else:
@@ -183,7 +234,7 @@ class MenuEditor:
 
 	def setVisible(self, item, visible):
 		dom = self.__getMenu(item).dom
-		if item.get_type() == gmenu.TYPE_ENTRY:
+		if isinstance(item, GMenu.TreeEntry):
 			self.__addUndo([self.__getMenu(item), item])
 			menu_xml = self.__getXmlMenu(self.__getPath(item.get_parent()), dom, dom)
 			if visible:
@@ -192,10 +243,12 @@ class MenuEditor:
 			else:
 				self.__addXmlFilename(menu_xml, dom, item.get_desktop_file_id(), 'Exclude')
 			self.__addXmlTextElement(menu_xml, 'AppDir', util.getUserItemPath(), dom)
-		elif item.get_type() == gmenu.TYPE_DIRECTORY:
+		elif isinstance(item, GMenu.TreeDirectory):
 			self.__addUndo([self.__getMenu(item), item])
+			item_iter = item.iter()
+			first_child_type = item_iter.next()
 			#don't mess with it if it's empty
-			if len(item.get_contents()) == 0:
+			if first_child_type == GMenu.TreeItemType.INVALID:
 				return
 			menu_xml = self.__getXmlMenu(self.__getPath(item), dom, dom)
 			for node in self.__getXmlNodesByName(['Deleted', 'NotDeleted'], menu_xml):
@@ -209,19 +262,26 @@ class MenuEditor:
 
 	def createItem(self, parent, icon, name, comment, command, use_term, before=None, after=None):
 		file_id = self.__writeItem(None, icon, name, comment, command, use_term)
-		self.insertExternalItem(file_id, parent.menu_id, before, after)
+		self.insertExternalItem(file_id, parent.get_menu_id(), before, after)
 
 	def insertExternalItem(self, file_id, parent_id, before=None, after=None):
+		self.applications.tree.get_root_directory()
 		parent = self.__findMenu(parent_id)
+		self.applications.tree.get_root_directory()
 		dom = self.__getMenu(parent).dom
+		self.applications.tree.get_root_directory()
 		self.__addItem(parent, file_id, dom)
+		self.applications.tree.get_root_directory()
 		self.__positionItem(parent, ('Item', file_id), before, after)
+		self.applications.tree.get_root_directory()
 		self.__addUndo([self.__getMenu(parent), ('Item', file_id)])
+		self.applications.tree.get_root_directory()
 		self.save()
+		self.applications.tree.get_root_directory()
 
 	def createMenu(self, parent, icon, name, comment, before=None, after=None):
 		file_id = self.__writeMenu(None, icon, name, comment)
-		self.insertExternalMenu(file_id, parent.menu_id, before, after)
+		self.insertExternalMenu(file_id, parent.get_menu_id(), before, after)
 
 	def insertExternalMenu(self, file_id, parent_id, before=None, after=None):
 		menu_id = file_id.rsplit('.', 1)[0]
@@ -241,7 +301,8 @@ class MenuEditor:
 
 	def editItem(self, item, icon, name, comment, command, use_term, parent=None, final=True):
 		#if nothing changed don't make a user copy
-		if icon == item.get_icon() and name == item.get_display_name() and comment == item.get_comment() and command == item.get_exec() and use_term == item.get_launch_in_terminal():
+		app_info = item.get_app_info()
+		if icon == app_info.get_icon() and name == app_info.get_display_name() and comment == item.get_comment() and command == item.get_exec() and use_term == item.get_launch_in_terminal():
 			return
 		#hack, item.get_parent() seems to fail a lot
 		if not parent:
@@ -276,7 +337,8 @@ class MenuEditor:
 		#erase Categories in new file
 		keyfile.set('Categories', ('',))
 		keyfile.set('Hidden', False)
-		file_id = util.getUniqueFileId(item.get_name().replace(os.sep, '-'), '.desktop')
+		app_info = item.get_info()
+		file_id = util.getUniqueFileId(app_info.get_name().replace(os.sep, '-'), '.desktop')
 		out_path = os.path.join(util.getUserItemPath(), file_id)
 		keyfile.write(open(out_path, 'w'))
 		self.__addItem(new_parent, file_id, dom)
@@ -355,7 +417,7 @@ class MenuEditor:
 
 	def deleteSeparator(self, item):
 		parent = item.get_parent()
-		contents = parent.get_contents()
+		contents = self.getContents(parent)
 		contents.remove(item)
 		layout = self.__createLayout(contents)
 		dom = self.__getMenu(parent).dom
@@ -406,13 +468,13 @@ class MenuEditor:
 						file_path = util.getDirectoryPath(item[1])
 				else:
 					continue
-			elif item.get_type() == gmenu.TYPE_DIRECTORY:
+			elif isinstance(item, GMenu.TreeDirectory):
 				if item.get_desktop_file_path() == None:
 					continue
 				file_path = os.path.join(util.getUserDirectoryPath(), os.path.split(item.get_desktop_file_path())[1])
 				if not os.path.isfile(file_path):
 					file_path = item.get_desktop_file_path()
-			elif item.get_type() == gmenu.TYPE_ENTRY:
+			elif isinstance(item, GMenu.TreeEntry):
 				file_path = os.path.join(util.getUserItemPath(), item.get_desktop_file_id())
 				if not os.path.isfile(file_path):
 					file_path = item.get_desktop_file_path()
@@ -427,36 +489,43 @@ class MenuEditor:
 		return self.applications
 
 	def __findMenu(self, menu_id, parent=None):
-		if parent == None:
-			return self.__findMenu(menu_id, self.applications.tree.root)
-		if menu_id == self.applications.tree.root.menu_id:
-			return self.applications.tree.root
-		for item in parent.get_contents():
-			if item.get_type() == gmenu.TYPE_DIRECTORY:
-				if item.menu_id == menu_id:
+		root_directory = self.applications.tree.get_root_directory()
+		if parent == None and root_directory != None:
+			return self.__findMenu(menu_id, root_directory)
+		if menu_id == root_directory.get_menu_id():
+			return root_directory
+		item_iter = parent.iter()
+		item_type = item_iter.next()
+		while item_type != GMenu.TreeItemType.INVALID:
+			if item_type == GMenu.TreeItemType.DIRECTORY:
+				item = item_iter.get_directory()
+				if item.get_menu_id() == menu_id:
 					return item
 				menu = self.__findMenu(menu_id, item)
 				if menu != None:
 					return menu
+			item_type = item_iter.next()
 
 	def __isVisible(self, item):
-		if item.get_type() == gmenu.TYPE_ENTRY:
-			return not (item.get_is_excluded() or item.get_is_nodisplay())
+		if isinstance(item, GMenu.TreeEntry):
+			app_info = item.get_app_info()
+			return not (item.get_is_excluded() or app_info.get_nodisplay())
 		menu = self.__getMenu(item)
 		if menu == self.applications:
-			root = self.applications.visible_tree.root
-		if item.get_type() == gmenu.TYPE_DIRECTORY:
-			if self.__findMenu(item.menu_id, root) == None:
+			root = self.applications.visible_tree.get_root_directory()
+		if isinstance(item, GMenu.TreeDirectory):
+			if self.__findMenu(item.get_menu_id(), root) == None:
 				return False
 		return True
 
 	def __getPath(self, menu, path=None):
 		if not path:
-                        path = menu.tree.root.get_menu_id()
+                        path = menu.get_menu_id()
 		if menu.get_parent():
 			path = self.__getPath(menu.get_parent(), path)
 			path += '/'
-			path += menu.menu_id
+			path += menu.get_menu_id()
+		print "%s\n" % path
 		return path
 
 	def __getXmlMenu(self, path, element, dom):
@@ -646,11 +715,11 @@ class MenuEditor:
 					layout.parseMenuname(item[1])
 				elif item[0] == 'Item':
 					layout.parseFilename(item[1])
-			elif item.get_type() == gmenu.TYPE_DIRECTORY:
+			elif isinstance(item, GMenu.TreeDirectory):
 				layout.parseMenuname(item.get_menu_id())
-			elif item.get_type() == gmenu.TYPE_ENTRY:
+			elif isinstance(item, GMenu.TreeEntry):
 				layout.parseFilename(item.get_desktop_file_id())
-			elif item.get_type() == gmenu.TYPE_SEPARATOR:
+			elif isinstance(item, GMenu.TreeSeparator):
 				layout.parseSeparator()
 		layout.order.append(['Merge', 'files'])
 		return layout
@@ -664,14 +733,14 @@ class MenuEditor:
 		self.__addXmlFilename(xml_parent, dom, file_id, 'Exclude')
 
 	def __positionItem(self, parent, item, before=None, after=None):
+		contents = self.getContents(parent)
 		if after:
-			index = parent.contents.index(after) + 1
+			index = contents.index(after) + 1
 		elif before:
-			index = parent.contents.index(before)
+			index = contents.index(before)
 		else:
 			# append the item to the list
-			index = len(parent.contents)
-		contents = parent.contents
+			index = len(contents)
 		#if this is a move to a new parent you can't remove the item
 		if item in contents:
 			# decrease the destination index, if we shorten the list
diff --git a/Alacarte/util.py b/Alacarte/util.py
index a916435..626f0ca 100644
--- a/Alacarte/util.py
+++ b/Alacarte/util.py
@@ -17,8 +17,7 @@
 #   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 import os
-from gi.repository import Gtk, GdkPixbuf
-import gmenu
+from gi.repository import Gtk, GdkPixbuf, GMenu
 from ConfigParser import ConfigParser
 
 class DesktopParser(ConfigParser):
@@ -194,8 +193,8 @@ def getSystemMenuPath(file_name):
 	return False
 
 def getUserMenuXml(tree):
-	system_file = getSystemMenuPath(tree.get_menu_file())
-	name = tree.root.get_menu_id()
+	system_file = getSystemMenuPath(os.path.basename(tree.get_canonical_menu_path()))
+	name = tree.get_root_directory().get_menu_id()
 	menu_xml = "<!DOCTYPE Menu PUBLIC '-//freedesktop//DTD Menu 1.0//EN' 'http://standards.freedesktop.org/menu-spec/menu-1.0.dtd'>\n"
 	menu_xml += "<Menu>\n  <Name>" + name + "</Name>\n  "
 	menu_xml += "<MergeFile type=\"parent\">" + system_file +	"</MergeFile>\n</Menu>\n"
@@ -207,29 +206,25 @@ def getIcon(item, for_properties=False):
 		if for_properties:
 			return None, None
 		return None
-	if isinstance(item, str):
-		iconName = item
+
+	if isinstance(item, GMenu.TreeDirectory):
+		gicon = item.get_icon()
 	else:
-		iconName = item.get_icon()
-	if iconName and not '/' in iconName and iconName[-3:] in ('png', 'svg', 'xpm'):
-		iconName = iconName[:-4]
+		app_info = item.get_app_info()
+		gicon = app_info.get_icon()
+
 	icon_theme = Gtk.IconTheme.get_default()
 	try:
-		pixbuf = icon_theme.load_icon(iconName, 24, 0)
-		path = icon_theme.lookup_icon(iconName, 24, 0).get_filename()
+		info = icon_theme.lookup_by_gicon(icon_theme, gicon, 24, 0)
+		pixbuf = icon.load_icon()
+		path = info.get_filename()
 	except:
-		if iconName and '/' in iconName:
-			try:
-				pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(iconName, 24, 24)
-				path = iconName
-			except:
-				pass
-		if pixbuf == None:
+		if pixbuf is None:
 			if for_properties:
 				return None, None
-			if item.get_type() == gmenu.TYPE_DIRECTORY:
+			if isinstance(item, GMenu.TreeDirectory):
 				iconName = 'gnome-fs-directory'
-			elif item.get_type() == gmenu.TYPE_ENTRY:
+			else:
 				iconName = 'application-default-icon'
 			try:
 				pixbuf = icon_theme.load_icon(iconName, 24, 0)
diff --git a/configure.ac b/configure.ac
index 2ca2611..228bc2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@ IT_PROG_INTLTOOL([0.40.0])
 
 AM_PATH_PYTHON_VERSION(2.7, 2.7.0, 2.6, 2.6.0, 2.5, 2.5.0, 2.4, 2.4.0)
 
-PKG_CHECK_MODULES(ALACARTE, libgnome-menu >= 2.27.92)
+PKG_CHECK_MODULES(ALACARTE, libgnome-menu-3.0 >= 3.2.0.1)
 
 dnl Check for correctly installed pygobject
 AC_MSG_CHECKING(for pygobject required_pygobject_version installed for python required_python_abi)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]