pidgin/pidgin

Parents 3bd059ab9eb4
Children 41733d530d58
Port the sort-method items to GMenu and GAction and display in the new menubar
--- a/pidgin/gtkblist.c Fri Mar 27 19:03:57 2020 -0500
+++ b/pidgin/gtkblist.c Mon Mar 30 22:47:30 2020 -0500
@@ -151,8 +151,6 @@
static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
-static guint sort_merge_id;
-static GtkActionGroup *sort_action_group = NULL;
static PidginBuddyList *gtkblist = NULL;
@@ -2009,12 +2007,6 @@
return handled;
}
-static void pidgin_blist_show_protocol_icons_cb(GtkToggleAction *item, gpointer data)
-{
- purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons",
- gtk_toggle_action_get_active(item));
-}
-
static void
add_buddies_from_vcard(const char *protocol_id, PurpleGroup *group, GList *list,
const char *alias)
@@ -5632,8 +5624,9 @@
menu = gtk_ui_manager_get_widget(gtkblist->ui, "/BList/AccountsMenu");
accountmenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu));
- menu = pidgin_buddy_list_menu_new();
- gtk_box_pack_start(GTK_BOX(gtkblist->main_vbox), menu, FALSE, FALSE, 0);
+ gtkblist->menu = pidgin_buddy_list_menu_new();
+ gtk_box_pack_start(GTK_BOX(gtkblist->main_vbox), gtkblist->menu, FALSE,
+ FALSE, 0);
/****************************** Notebook *************************************/
gtkblist->notebook = gtk_notebook_new();
@@ -8052,74 +8045,38 @@
g_object_unref(action_group);
}
-static void
-sortmethod_act(GtkRadioAction *action, GtkRadioAction *current, char *id)
-{
- if (action == current)
- {
- pidgin_set_cursor(gtkblist->window, GDK_WATCH);
- /* This is redundant. I think. */
- /* pidgin_blist_sort_method_set(id); */
- purple_prefs_set_string(PIDGIN_PREFS_ROOT "/blist/sort_type", id);
-
- pidgin_clear_cursor(gtkblist->window);
- }
-}
-
void
pidgin_blist_update_sort_methods(void)
{
- PidginBlistSortMethod *method = NULL;
+ GtkWidget *sort_item = NULL;
+ GMenu *menu = NULL;
GList *l;
- GSList *sl = NULL;
- const char *m = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/sort_type");
-
- GtkRadioAction *action;
- GString *ui_string;
if ((gtkblist == NULL) || (gtkblist->ui == NULL))
return;
- /* Clear the old menu */
- if (sort_action_group) {
- gtk_ui_manager_remove_ui(gtkblist->ui, sort_merge_id);
- gtk_ui_manager_remove_action_group(gtkblist->ui, sort_action_group);
- g_object_unref(G_OBJECT(sort_action_group));
- }
-
- sort_action_group = gtk_action_group_new("SortMethods");
- gtk_action_group_set_translation_domain(sort_action_group, PACKAGE);
-
- ui_string = g_string_new("<ui><menubar name='BList'>"
- "<menu action='BuddiesMenu'><menu action='SortMenu'>");
-
+ /* create the gmenu */
+ menu = g_menu_new();
+
+ /* walk through the sort methods and update all the things */
for (l = pidgin_blist_sort_methods; l; l = l->next) {
+ PidginBlistSortMethod *method = NULL;
+ GMenuItem *item = NULL;
+ gchar *action = NULL;
+
method = (PidginBlistSortMethod *)l->data;
- g_string_append_printf(ui_string, "<menuitem action='%s'/>", method->id);
- action = gtk_radio_action_new(method->id,
- method->name,
- NULL,
- NULL,
- 0);
- gtk_action_group_add_action_with_accel(sort_action_group, GTK_ACTION(action), NULL);
-
- gtk_radio_action_set_group(action, sl);
- sl = gtk_radio_action_get_group(action);
-
- if (purple_strequal(m, method->id))
- gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE);
- else
- gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), FALSE);
-
- g_signal_connect(G_OBJECT(action), "changed",
- G_CALLBACK(sortmethod_act), method->id);
- }
-
- g_string_append(ui_string, "</menu></menu></menubar></ui>");
- gtk_ui_manager_insert_action_group(gtkblist->ui, sort_action_group, 1);
- sort_merge_id = gtk_ui_manager_add_ui_from_string(gtkblist->ui, ui_string->str, -1, NULL);
-
- g_string_free(ui_string, TRUE);
-}
-
+ action = g_action_print_detailed_name("blist.sort-method",
+ g_variant_new_string(method->id));
+ item = g_menu_item_new(method->name, action);
+ g_free(action);
+
+ g_menu_append_item(menu, item);
+ }
+
+ /* replace the old submenu with a new one */
+ sort_item = pidgin_buddy_list_menu_get_sort_item(PIDGIN_BUDDY_LIST_MENU(gtkblist->menu));
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(sort_item),
+ gtk_menu_new_from_model(menu));
+ g_object_unref(G_OBJECT(menu));
+}
--- a/pidgin/gtkblist.h Fri Mar 27 19:03:57 2020 -0500
+++ b/pidgin/gtkblist.h Mon Mar 30 22:47:30 2020 -0500
@@ -120,6 +120,7 @@
GtkCellRenderer *text_rend;
GtkUIManager *ui;
+ GtkWidget *menu;
GtkWidget *menutray;
GtkWidget *menutrayicon;
--- a/pidgin/pidginactiongroup.c Fri Mar 27 19:03:57 2020 -0500
+++ b/pidgin/pidginactiongroup.c Mon Mar 30 22:47:30 2020 -0500
@@ -46,7 +46,7 @@
* Helpers
*****************************************************************************/
-/*<private>
+/*< private >
* pidgin_action_group_bool_pref_handler:
* @group: The #PidginActionGroup instance.
* @action_name: The name of the action to update.
@@ -72,7 +72,7 @@
}
}
-/*<private
+/*< private >
* pidgin_action_group_setup_bool:
* @group: The #PidginActionGroup instance.
* @action_name: The name of the action to setup.
@@ -110,6 +110,68 @@
purple_prefs_connect_callback(group, pref_name, callback, group);
}
+/*< private >
+ * pidgin_action_group_string_pref_handler:
+ * @group: The #PidginActionGroup instance.
+ * @action_name: The name of the action to update.
+ * @value: The value of the preference.
+ *
+ * Changes the state of the action named @action_name to match @value.
+ *
+ * This function is meant to be called from a #PurplePrefCallback function as
+ * there isn't a good way to have a #PurplePrefCallback with multiple items in
+ * the data parameter without leaking them forever.
+ */
+static void
+pidgin_action_group_string_pref_handler(PidginActionGroup *group,
+ const gchar *action_name,
+ const gchar *value)
+{
+ GAction *action = NULL;
+
+ action = g_action_map_lookup_action(G_ACTION_MAP(group), action_name);
+ if(action != NULL) {
+ g_simple_action_set_state(G_SIMPLE_ACTION(action),
+ g_variant_new_string(value));
+ }
+}
+
+/*< private >
+ * pidgin_action_group_setup_string:
+ * @group: The #PidginActionGroup instance.
+ * @action_name: The name of the action to setup.
+ * @pref_name: The name of the preference that @action_name is tied to.
+ * @callback: (scope call): A #PurplePrefCallback to call when the preference
+ * is changed.
+ *
+ * Initializes the string action named @action_name to the value of @pref_name
+ * and setups up a preference change callback to @callback to maintain the
+ * state of the action.
+ */
+static void
+pidgin_action_group_setup_string(PidginActionGroup *group,
+ const gchar *action_name,
+ const gchar *pref_name,
+ PurplePrefCallback callback)
+{
+ GAction *action = NULL;
+ const gchar *value = NULL;
+
+ /* find the action, if we can't find it, bail */
+ action = g_action_map_lookup_action(G_ACTION_MAP(group), action_name);
+ g_return_if_fail(action != NULL);
+
+ /* change the state of the action to match the preference value. */
+ value = purple_prefs_get_string(pref_name);
+ g_simple_action_set_state(G_SIMPLE_ACTION(action),
+ g_variant_new_string(value));
+
+ /* finally add a preference callback to update the state based on the
+ * preference.
+ */
+ purple_prefs_connect_callback(group, pref_name, callback, group);
+}
+
/******************************************************************************
* Preference Callbacks
*****************************************************************************/
@@ -190,6 +252,19 @@
(gboolean)GPOINTER_TO_INT(value));
}
+static void
+pidgin_action_group_sort_method_callback(const gchar *name,
+ PurplePrefType type,
+ gconstpointer value,
+ gpointer data)
+{
+ PidginActionGroup *group = PIDGIN_ACTION_GROUP(data);
+
+ pidgin_action_group_string_pref_handler(group,
+ PIDGIN_ACTION_SORT_METHOD,
+ value);
+}
+
/******************************************************************************
* Action Callbacks
*****************************************************************************/
@@ -365,6 +440,14 @@
}
static void
+pidgin_action_group_sort_method(GSimpleAction *action, GVariant *value,
+ gpointer data)
+{
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/blist/sort_type",
+ g_variant_get_string(value, NULL));
+}
+
+static void
pidgin_action_group_system_log(GSimpleAction *simple, GVariant *parameter,
gpointer data)
{
@@ -457,6 +540,11 @@
.state = "false",
.change_state = pidgin_action_group_show_protocol_icons,
}, {
+ .name = PIDGIN_ACTION_SORT_METHOD,
+ .parameter_type = "s",
+ .state = "'none'",
+ .change_state = pidgin_action_group_sort_method,
+ }, {
.name = PIDGIN_ACTION_SYSTEM_LOG,
.activate = pidgin_action_group_system_log,
}, {
@@ -489,6 +577,10 @@
pidgin_action_group_setup_bool(group, PIDGIN_ACTION_SHOW_PROTOCOL_ICONS,
PIDGIN_PREFS_ROOT "/blist/show_protocol_icons",
pidgin_action_group_show_protocol_icons_callback);
+
+ pidgin_action_group_setup_string(group, PIDGIN_ACTION_SORT_METHOD,
+ PIDGIN_PREFS_ROOT "/blist/sort_type",
+ pidgin_action_group_sort_method_callback);
};
static void
--- a/pidgin/pidginactiongroup.h Fri Mar 27 19:03:57 2020 -0500
+++ b/pidgin/pidginactiongroup.h Mon Mar 30 22:47:30 2020 -0500
@@ -179,6 +179,14 @@
#define PIDGIN_ACTION_SHOW_PROTOCOL_ICONS ("show-protocol-icons")
/**
+ * PIDGIN_ACTION_SORT_METHOD:
+ *
+ * A constant that represents the sort-method action to change the sorting
+ * method of the buddy list.
+ */
+#define PIDGIN_ACTION_SORT_METHOD ("sort-method")
+
+/**
* PIDGIN_ACTION_SYSTEM_LOG:
*
* A constant that represents the system-log action.
--- a/pidgin/pidginbuddylistmenu.c Fri Mar 27 19:03:57 2020 -0500
+++ b/pidgin/pidginbuddylistmenu.c Mon Mar 30 22:47:30 2020 -0500
@@ -24,6 +24,8 @@
struct _PidginBuddyListMenu {
GtkMenuBar parent;
+
+ GtkWidget *sort_buddies;
};
/******************************************************************************
@@ -38,10 +40,15 @@
static void
pidgin_buddy_list_menu_class_init(PidginBuddyListMenuClass *klass) {
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
gtk_widget_class_set_template_from_resource(
- GTK_WIDGET_CLASS(klass),
+ widget_class,
"/im/pidgin/Pidgin/BuddyList/menu.ui"
);
+
+ gtk_widget_class_bind_template_child(widget_class, PidginBuddyListMenu,
+ sort_buddies);
}
/******************************************************************************
@@ -51,3 +58,10 @@
pidgin_buddy_list_menu_new(void) {
return GTK_WIDGET(g_object_new(PIDGIN_TYPE_BUDDY_LIST_MENU, NULL));
}
+
+GtkWidget *
+pidgin_buddy_list_menu_get_sort_item(PidginBuddyListMenu *menu) {
+ g_return_val_if_fail(PIDGIN_IS_BUDDY_LIST_MENU(menu), NULL);
+
+ return menu->sort_buddies;
+}
--- a/pidgin/pidginbuddylistmenu.h Fri Mar 27 19:03:57 2020 -0500
+++ b/pidgin/pidginbuddylistmenu.h Mon Mar 30 22:47:30 2020 -0500
@@ -41,6 +41,16 @@
*/
GtkWidget *pidgin_buddy_list_menu_new(void);
+/**
+ * pidgin_buddy_list_menu_get_sort_item:
+ * @menu: The #PidginBuddyList instance.
+ *
+ * Returns the sort menu item from the buddies menu.
+ *
+ * Returns: (transfer none): The sort menu item from the buddies menu.
+ */
+GtkWidget *pidgin_buddy_list_menu_get_sort_item(PidginBuddyListMenu *menu);
+
G_END_DECLS
#endif /* PIDGIN_BUDDY_LIST_MENU_H */
--- a/pidgin/resources/BuddyList/menu.ui Fri Mar 27 19:03:57 2020 -0500
+++ b/pidgin/resources/BuddyList/menu.ui Mon Mar 30 22:47:30 2020 -0500
@@ -121,7 +121,7 @@
</object>
</child>
<child>
- <object class="GtkMenuItem">
+ <object class="GtkMenuItem" id="sort_buddies">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Sort Buddies</property>