[gnome-menus] [libmenu, python] Add gmenu_tree_get_sort_key()/gmenu_tree_set_sort_key()
- From: Vincent Untz <vuntz src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-menus] [libmenu, python] Add gmenu_tree_get_sort_key()/gmenu_tree_set_sort_key()
- Date: Mon, 7 Sep 2009 23:29:58 +0000 (UTC)
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]