[gnome-menus] [libmenu, python] Add gmenu_tree_get_sort_key()/gmenu_tree_set_sort_key()



commit d3fdd0ba4133c66e670561bca5b1bf4dd1a8feea
Author: Vincent Untz <vuntz gnome org>
Date:   Mon Sep 7 23:13:22 2009 +0200

    [libmenu,python] Add gmenu_tree_get_sort_key()/gmenu_tree_set_sort_key()
    
    This is needed for users of gnome-menus that display applications by
    strings obtained via get_display_name(), since the order of entry
    changes if strings are different.
    
    The default is to keep the sort order by name. At the moment, the only
    other option is to use a sort by display name.
    
    Bindings for python are added too.

 libmenu/gmenu-tree.c |  121 +++++++++++++++++++++++++++++++++++--------------
 libmenu/gmenu-tree.h |   12 +++++
 python/gmenu.c       |   97 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 193 insertions(+), 37 deletions(-)
---
diff --git a/libmenu/gmenu-tree.c b/libmenu/gmenu-tree.c
index 6d50927..84196b7 100644
--- a/libmenu/gmenu-tree.c
+++ b/libmenu/gmenu-tree.c
@@ -51,6 +51,7 @@ struct GMenuTree
   char *canonical_path;
 
   GMenuTreeFlags flags;
+  GMenuTreeSortKey sort_key;
 
   GSList *menu_file_monitors;
 
@@ -643,6 +644,8 @@ gmenu_tree_new (GMenuTreeType   type,
   tree->flags    = flags;
   tree->refcount = 1;
 
+  tree->sort_key = GMENU_TREE_SORT_NAME;
+
   if (tree->type == GMENU_TREE_BASENAME)
     {
       g_assert (canonical == FALSE);
@@ -864,6 +867,31 @@ gmenu_tree_get_directory_from_path (GMenuTree  *tree,
   return directory ? gmenu_tree_item_ref (directory) : NULL;
 }
 
+GMenuTreeSortKey
+gmenu_tree_get_sort_key (GMenuTree *tree)
+{
+  g_return_val_if_fail (tree != NULL, GMENU_TREE_SORT_NAME);
+  g_return_val_if_fail (tree->refcount > 0, GMENU_TREE_SORT_NAME);
+
+  return tree->sort_key;
+}
+
+void
+gmenu_tree_set_sort_key (GMenuTree        *tree,
+			 GMenuTreeSortKey  sort_key)
+{
+  g_return_if_fail (tree != NULL);
+  g_return_if_fail (tree->refcount > 0);
+  g_return_if_fail (sort_key >= GMENU_TREE_SORT_FIRST);
+  g_return_if_fail (sort_key <= GMENU_TREE_SORT_LAST);
+
+  if (sort_key == tree->sort_key)
+    return;
+
+  tree->sort_key = sort_key;
+  gmenu_tree_force_rebuild (tree);
+}
+
 void
 gmenu_tree_add_monitor (GMenuTree            *tree,
                        GMenuTreeChangedFunc   callback,
@@ -1468,10 +1496,25 @@ gmenu_tree_entry_finalize (GMenuTreeEntry *entry)
 
 static int
 gmenu_tree_entry_compare (GMenuTreeEntry *a,
-			  GMenuTreeEntry *b)
+			  GMenuTreeEntry *b,
+			  gpointer        sort_key_p)
 {
-  return g_utf8_collate (desktop_entry_get_name (a->desktop_entry),
-                         desktop_entry_get_name (b->desktop_entry));
+  GMenuTreeSortKey sort_key;
+
+  sort_key = GPOINTER_TO_INT (sort_key_p);
+
+  switch (sort_key)
+    {
+    case GMENU_TREE_SORT_NAME:
+      return g_utf8_collate (desktop_entry_get_name (a->desktop_entry),
+			     desktop_entry_get_name (b->desktop_entry));
+    case GMENU_TREE_SORT_DISPLAY_NAME:
+      return g_utf8_collate (gmenu_tree_entry_get_display_name (a),
+			     gmenu_tree_entry_get_display_name (b));
+    default:
+      g_assert_not_reached ();
+      return 0;
+    }
 }
 
 static int
@@ -1580,24 +1623,34 @@ gmenu_tree_item_get_user_data (GMenuTreeItem *item)
   return item->user_data;
 }
 
-static int
-gmenu_tree_item_compare (GMenuTreeItem *a,
-			 GMenuTreeItem *b)
+static inline const char *
+gmenu_tree_item_compare_get_name_helper (GMenuTreeItem    *item,
+					 GMenuTreeSortKey  sort_key)
 {
-  const char *name_a;
-  const char *name_b;
+  const char *name;
 
-  switch (a->type)
+  switch (item->type)
     {
     case GMENU_TREE_ITEM_DIRECTORY:
-      if (GMENU_TREE_DIRECTORY (a)->directory_entry)
-	name_a = desktop_entry_get_name (GMENU_TREE_DIRECTORY (a)->directory_entry);
+      if (GMENU_TREE_DIRECTORY (item)->directory_entry)
+	name = desktop_entry_get_name (GMENU_TREE_DIRECTORY (item)->directory_entry);
       else
-	name_a = GMENU_TREE_DIRECTORY (a)->name;
+	name = GMENU_TREE_DIRECTORY (item)->name;
       break;
 
     case GMENU_TREE_ITEM_ENTRY:
-      name_a = desktop_entry_get_name (GMENU_TREE_ENTRY (a)->desktop_entry);
+      switch (sort_key)
+	{
+	case GMENU_TREE_SORT_NAME:
+	  name = desktop_entry_get_name (GMENU_TREE_ENTRY (item)->desktop_entry);
+	  break;
+	case GMENU_TREE_SORT_DISPLAY_NAME:
+	  gmenu_tree_entry_get_display_name (GMENU_TREE_ENTRY (item));
+	  break;
+	default:
+	  g_assert_not_reached ();
+	  break;
+	}
       break;
 
     case GMENU_TREE_ITEM_SEPARATOR:
@@ -1608,26 +1661,22 @@ gmenu_tree_item_compare (GMenuTreeItem *a,
       break;
     }
 
-  switch (b->type)
-    {
-    case GMENU_TREE_ITEM_DIRECTORY:
-      if (GMENU_TREE_DIRECTORY (b)->directory_entry)
-	name_b = desktop_entry_get_name (GMENU_TREE_DIRECTORY (b)->directory_entry);
-      else
-	name_b = GMENU_TREE_DIRECTORY (b)->name;
-      break;
+  return name;
+}
 
-    case GMENU_TREE_ITEM_ENTRY:
-      name_b = desktop_entry_get_name (GMENU_TREE_ENTRY (b)->desktop_entry);
-      break;
+static int
+gmenu_tree_item_compare (GMenuTreeItem *a,
+			 GMenuTreeItem *b,
+			 gpointer       sort_key_p)
+{
+  const char       *name_a;
+  const char       *name_b;
+  GMenuTreeSortKey  sort_key;
 
-    case GMENU_TREE_ITEM_SEPARATOR:
-    case GMENU_TREE_ITEM_HEADER:
-    case GMENU_TREE_ITEM_ALIAS:
-    default:
-      g_assert_not_reached ();
-      break;
-    }
+  sort_key = GPOINTER_TO_INT (sort_key_p);
+
+  name_a = gmenu_tree_item_compare_get_name_helper (a, sort_key);
+  name_b = gmenu_tree_item_compare_get_name_helper (b, sort_key);
 
   return g_utf8_collate (name_a, name_b);
 }
@@ -4108,8 +4157,9 @@ merge_entries (GMenuTree          *tree,
   entries = directory->entries;
   directory->entries = NULL;
 
-  entries = g_slist_sort (entries,
-			  (GCompareFunc) gmenu_tree_entry_compare);
+  entries = g_slist_sort_with_data (entries,
+				    (GCompareDataFunc) gmenu_tree_entry_compare,
+				    GINT_TO_POINTER (tree->sort_key));
 
   tmp = entries;
   while (tmp != NULL)
@@ -4151,8 +4201,9 @@ merge_subdirs_and_entries (GMenuTree          *tree,
   directory->subdirs = NULL;
   directory->entries = NULL;
 
-  items = g_slist_sort (items,
-			(GCompareFunc) gmenu_tree_item_compare);
+  items = g_slist_sort_with_data (items,
+				  (GCompareDataFunc) gmenu_tree_item_compare,
+				  GINT_TO_POINTER (tree->sort_key));
 
   tmp = items;
   while (tmp != NULL)
diff --git a/libmenu/gmenu-tree.h b/libmenu/gmenu-tree.h
index 72bb1e4..3a05eb2 100644
--- a/libmenu/gmenu-tree.h
+++ b/libmenu/gmenu-tree.h
@@ -66,6 +66,14 @@ typedef enum
   GMENU_TREE_FLAGS_MASK                = 0x0f
 } GMenuTreeFlags;
 
+typedef enum
+{
+  #define GMENU_TREE_SORT_FIRST GMENU_TREE_SORT_NAME
+  GMENU_TREE_SORT_NAME = 0,
+  GMENU_TREE_SORT_DISPLAY_NAME
+  #define GMENU_TREE_SORT_LAST GMENU_TREE_SORT_DISPLAY_NAME
+} GMenuTreeSortKey;
+
 GMenuTree *gmenu_tree_lookup (const char     *menu_file,
 			      GMenuTreeFlags  flags);
 
@@ -82,6 +90,10 @@ GMenuTreeDirectory *gmenu_tree_get_root_directory      (GMenuTree  *tree);
 GMenuTreeDirectory *gmenu_tree_get_directory_from_path (GMenuTree  *tree,
 							const char *path);
 
+GMenuTreeSortKey     gmenu_tree_get_sort_key (GMenuTree        *tree);
+void                 gmenu_tree_set_sort_key (GMenuTree        *tree,
+					      GMenuTreeSortKey  sort_key);
+
 
 
 gpointer gmenu_tree_item_ref   (gpointer item);
diff --git a/python/gmenu.c b/python/gmenu.c
index 8f3d7e6..71e4e38 100644
--- a/python/gmenu.c
+++ b/python/gmenu.c
@@ -1515,6 +1515,56 @@ pygmenu_tree_get_directory_from_path (PyObject *self,
   return (PyObject *) retval;
 }
 
+static PyObject *
+pygmenu_tree_get_sort_key (PyObject *self,
+			   PyObject *args)
+{
+  PyGMenuTree *tree;
+  PyObject    *retval;
+
+  if (args != NULL)
+    {
+      if (!PyArg_ParseTuple (args, ":gmenu.Tree.get_sort_key"))
+	return NULL;
+    }
+
+  tree = (PyGMenuTree *) self;
+
+  switch (gmenu_tree_get_sort_key (tree->tree))
+    {
+    case GMENU_TREE_SORT_NAME:
+      retval = lookup_item_type_str ("SORT_NAME");
+      break;
+
+    case GMENU_TREE_SORT_DISPLAY_NAME:
+      retval = lookup_item_type_str ("SORT_DISPLAY_NAME");
+      break;
+
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
+  return (PyObject *) retval;
+}
+
+static PyObject *
+pygmenu_tree_set_sort_key (PyObject *self,
+			   PyObject *args)
+{
+  PyGMenuTree *tree;
+  int          sort_key;
+
+  if (!PyArg_ParseTuple (args, "i:gmenu.Tree.set_sort_key", &sort_key))
+    return NULL;
+
+  tree = (PyGMenuTree *) self;
+
+  gmenu_tree_set_sort_key (tree->tree, sort_key);
+
+  return Py_None;
+}
+
 static PyGMenuTreeCallback *
 pygmenu_tree_callback_new (PyObject *tree,
 			   PyObject *callback,
@@ -1680,7 +1730,7 @@ pygmenu_tree_getattro (PyGMenuTree *self,
 
       if (!strcmp (attr, "__members__"))
 	{
-	  return Py_BuildValue ("[ss]", "root", "menu_file");
+	  return Py_BuildValue ("[sss]", "root", "menu_file", "sort_key");
 	}
       else if (!strcmp (attr, "root"))
 	{
@@ -1690,16 +1740,56 @@ pygmenu_tree_getattro (PyGMenuTree *self,
 	{
 	  return pygmenu_tree_get_menu_file ((PyObject *) self, NULL);
 	}
+      else if (!strcmp (attr, "sort_key"))
+	{
+	  return pygmenu_tree_get_sort_key ((PyObject *) self, NULL);
+	}
     }
 
   return PyObject_GenericGetAttr ((PyObject *) self, py_attr);
 }
 
+static int
+pygmenu_tree_setattro (PyGMenuTree *self,
+		       PyObject    *py_attr,
+		       PyObject    *py_value)
+{
+  PyGMenuTree *tree;
+
+  tree = (PyGMenuTree *) self;
+
+  if (PyString_Check (py_attr))
+    {
+      char *attr;
+
+      attr = PyString_AsString (py_attr);
+
+      if (!strcmp (attr, "sort_key"))
+	{
+	  if (PyInt_Check (py_value))
+	    {
+	      int sort_key;
+
+	      sort_key = PyInt_AsLong (py_value);
+	      if (sort_key < GMENU_TREE_SORT_FIRST || sort_key > GMENU_TREE_SORT_LAST)
+		return -1;
+	      gmenu_tree_set_sort_key (tree->tree, sort_key);
+
+	      return 0;
+	    }
+	}
+    }
+
+  return -1;
+}
+
 static struct PyMethodDef pygmenu_tree_methods[] =
 {
   { "get_menu_file",           pygmenu_tree_get_menu_file,           METH_VARARGS },
   { "get_root_directory",      pygmenu_tree_get_root_directory,      METH_VARARGS },
   { "get_directory_from_path", pygmenu_tree_get_directory_from_path, METH_VARARGS },
+  { "get_sort_key",            pygmenu_tree_get_sort_key,            METH_VARARGS },
+  { "set_sort_key",            pygmenu_tree_set_sort_key,            METH_VARARGS },
   { "add_monitor",             pygmenu_tree_add_monitor,             METH_VARARGS },
   { "remove_monitor",          pygmenu_tree_remove_monitor,          METH_VARARGS },
   { NULL,                      NULL,                                 0            }
@@ -1725,7 +1815,7 @@ static PyTypeObject PyGMenuTree_Type =
   (ternaryfunc)0,                      /* tp_call */
   (reprfunc)0,                         /* tp_str */
   (getattrofunc)pygmenu_tree_getattro, /* tp_getattro */
-  (setattrofunc)0,                     /* tp_setattro */
+  (setattrofunc)pygmenu_tree_setattro, /* tp_setattro */
   0,                                   /* tp_as_buffer */
   Py_TPFLAGS_DEFAULT,                  /* tp_flags */
   NULL,                                /* Documentation string */
@@ -1851,4 +1941,7 @@ initgmenu (void)
   PyModule_AddIntConstant (mod, "FLAGS_SHOW_EMPTY",          GMENU_TREE_FLAGS_SHOW_EMPTY);
   PyModule_AddIntConstant (mod, "FLAGS_INCLUDE_NODISPLAY",   GMENU_TREE_FLAGS_INCLUDE_NODISPLAY);
   PyModule_AddIntConstant (mod, "FLAGS_SHOW_ALL_SEPARATORS", GMENU_TREE_FLAGS_SHOW_ALL_SEPARATORS);
+
+  PyModule_AddIntConstant (mod, "SORT_NAME",         GMENU_TREE_SORT_NAME);
+  PyModule_AddIntConstant (mod, "SORT_DISPLAY_NAME", GMENU_TREE_SORT_DISPLAY_NAME);
 }



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