pidgin/pidginaccountsdisabledmenu.c

Sun, 10 Nov 2024 03:55:48 -0600

author
Gary Kramlich <grim@reaperworld.com>
date
Sun, 10 Nov 2024 03:55:48 -0600
changeset 43062
9d134b69b834
parent 42804
be8c8b5471ca
child 43220
583158d1e6c2
permissions
-rw-r--r--

Update Pidgin for the Purple.Account.get_protocol_name deprecations

Testing Done:
Modified `accounts.xml` to setup an invalid protocol and verified the menu and account editor display the account properly. Called in the turtles for good measure.

Reviewed at https://reviews.imfreedom.org/r/3651/

/*
 * Pidgin - Internet Messenger
 * Copyright (C) Pidgin Developers <devel@pidgin.im>
 *
 * Pidgin is the legal property of its developers, whose names are too numerous
 * to list here.  Please refer to the COPYRIGHT file distributed with this
 * source distribution.
 *
 * 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, see <https://www.gnu.org/licenses/>.
 */

#include <glib/gi18n.h>

#include "pidginaccountsdisabledmenu.h"

struct _PidginAccountsDisabledMenu {
	GMenuModel parent;

	GList *accounts;
};

G_DEFINE_FINAL_TYPE(PidginAccountsDisabledMenu, pidgin_accounts_disabled_menu,
                    G_TYPE_MENU_MODEL)

/******************************************************************************
 * Callbacks
 *****************************************************************************/
static void
pidgin_accounts_disabled_menu_refresh(PidginAccountsDisabledMenu *menu) {
	PurpleAccountManager *manager = NULL;
	gint removed = 0, added = 0;

	/* When refreshing we're always removing at least 1 item because of the
	 * "no disabled accounts" item that we put in place when all accounts
	 * are enabled.
	 */
	removed = MAX(1, g_list_length(menu->accounts));

	/* Grab the manager and get all the disabled accounts. */
	manager = purple_account_manager_get_default();
	g_list_free(menu->accounts);
	menu->accounts = purple_account_manager_get_disabled(manager);

	/* Similar to the above note about removed items, if every account is
	 * enabled, we add an item saying "no disabled accounts".
	 */
	added = MAX(1, g_list_length(menu->accounts));

	/* Tell any listeners that our menu has changed. */
	g_menu_model_items_changed(G_MENU_MODEL(menu), 0, removed, added);
}

static void
pidgin_accounts_disabled_menu_changed_cb(G_GNUC_UNUSED PurpleAccountManager *manager,
                                         G_GNUC_UNUSED PurpleAccount *account,
                                         G_GNUC_UNUSED GParamSpec *pspec,
                                         gpointer data)
{
	PidginAccountsDisabledMenu *menu = data;

	pidgin_accounts_disabled_menu_refresh(menu);
}

/******************************************************************************
 * GMenuModel Implementation
 *****************************************************************************/
static gboolean
pidgin_accounts_disabled_menu_is_mutable(G_GNUC_UNUSED GMenuModel *model) {
	return TRUE;
}

static gboolean
pidgin_accounts_disabled_menu_get_n_items(GMenuModel *model) {
	PidginAccountsDisabledMenu *menu = NULL;

	menu = PIDGIN_ACCOUNTS_DISABLED_MENU(model);

	if(menu->accounts == NULL) {
		return 1;
	}

	return g_list_length(menu->accounts);
}

static void
pidgin_accounts_disabled_menu_get_item_attributes(GMenuModel *model,
                                                  gint index,
                                                  GHashTable **attributes)
{
	PidginAccountsDisabledMenu *menu = NULL;
	PurpleAccount *account = NULL;
	PurpleProtocol *protocol = NULL;
	GVariant *value = NULL;
	const char *account_name = NULL;
	const char *protocol_name = N_("Unknown");

	menu = PIDGIN_ACCOUNTS_DISABLED_MENU(model);

	/* Create our hash table of attributes to return. */
	*attributes = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
	                                    (GDestroyNotify)g_variant_unref);

	/* If we don't have any disabled accounts, just return a single item,
	 * stating as much.
	 */
	if(menu->accounts == NULL) {
		value = g_variant_new_string(_("No disabled accounts"));
		g_hash_table_insert(*attributes, G_MENU_ATTRIBUTE_LABEL,
		                    g_variant_ref_sink(value));

		value = g_variant_new_string("disabled");
		g_hash_table_insert(*attributes, G_MENU_ATTRIBUTE_ACTION,
		                    g_variant_ref_sink(value));

		return;
	}

	account = g_list_nth_data(menu->accounts, index);
	if(account == NULL) {
		return;
	}

	account_name = purple_account_get_username(account);
	protocol = purple_account_get_protocol(account);
	if(PURPLE_IS_PROTOCOL(protocol)) {
		protocol_name = purple_protocol_get_name(protocol);

		value = g_variant_new_printf("%s", purple_protocol_get_icon_name(protocol));
		g_hash_table_insert(*attributes, G_MENU_ATTRIBUTE_ICON,
		                    g_variant_ref_sink(value));
	}

	/* translators: This format string is intended to contain the account
	 * name followed by the protocol name to uniquely identify a specific
	 * account.
	 */
	value = g_variant_new_printf(_("%s (%s)"), account_name, _(protocol_name));
	g_hash_table_insert(*attributes, G_MENU_ATTRIBUTE_LABEL,
	                    g_variant_ref_sink(value));

	value = g_variant_new_string("app.enable-account");
	g_hash_table_insert(*attributes, G_MENU_ATTRIBUTE_ACTION,
	                    g_variant_ref_sink(value));

	value = g_variant_new_printf("%s", purple_account_get_id(account));
	g_hash_table_insert(*attributes, G_MENU_ATTRIBUTE_TARGET,
	                    g_variant_ref_sink(value));
}

static void
pidgin_accounts_disabled_menu_get_item_links(G_GNUC_UNUSED GMenuModel *model,
                                             G_GNUC_UNUSED gint index,
                                             GHashTable **links)
{
	*links = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
	                               g_object_unref);
}

/******************************************************************************
 * GObject Implementation
 *****************************************************************************/
static void
pidgin_accounts_disabled_menu_constructed(GObject *obj) {
	G_OBJECT_CLASS(pidgin_accounts_disabled_menu_parent_class)->constructed(obj);

	pidgin_accounts_disabled_menu_refresh(PIDGIN_ACCOUNTS_DISABLED_MENU(obj));
}

static void
pidgin_accounts_disabled_menu_init(PidginAccountsDisabledMenu *menu) {
	PurpleAccountManager *manager = purple_account_manager_get_default();

	g_signal_connect_object(manager, "account-changed::enabled",
	                        G_CALLBACK(pidgin_accounts_disabled_menu_changed_cb),
	                        menu, 0);
}

static void
pidgin_accounts_disabled_menu_class_init(PidginAccountsDisabledMenuClass *klass) {
	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
	GMenuModelClass *model_class = G_MENU_MODEL_CLASS(klass);

	obj_class->constructed = pidgin_accounts_disabled_menu_constructed;

	model_class->is_mutable = pidgin_accounts_disabled_menu_is_mutable;
	model_class->get_n_items = pidgin_accounts_disabled_menu_get_n_items;
	model_class->get_item_attributes = pidgin_accounts_disabled_menu_get_item_attributes;
	model_class->get_item_links = pidgin_accounts_disabled_menu_get_item_links;
}

/******************************************************************************
 * Public API
 *****************************************************************************/
GMenuModel *
pidgin_accounts_disabled_menu_new(void) {
	return g_object_new(PIDGIN_TYPE_ACCOUNTS_DISABLED_MENU, NULL);
}

mercurial