Thu, 06 Aug 2020 22:22:03 -0500
pidgin.h phase3: create pidgin.h and force its usage
fix the section id of pidgincore.h
Generate our pidgin.h file
Add include guard to all pidgin/*.h files and deal with the fallout from that.
Also had to namespace PIDGIN_BLIST_COLUMN_NAME, will come back and get the rest at a later time.
Testing Done:
Compile test, including some plugins that don't build by default. Also ran everything seems fine.
Reviewed at https://reviews.imfreedom.org/r/50/
/* * pidgin * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "pidginaccountsmenu.h" #include <purple.h> #include "pidginaccountactionsmenu.h" #include "gtkaccount.h" #include "pidgincore.h" struct _PidginAccountsMenu { GtkMenu parent; GtkWidget *disabled_menu; GtkWidget *separator; GHashTable *account_items; GHashTable *disabled_items; }; /****************************************************************************** * GSignal Handlers *****************************************************************************/ static void pidgin_accounts_menu_open_manager_cb(GtkMenuItem *item, gpointer data) { pidgin_accounts_window_show(); } static void pidgin_accounts_menu_enable_account(GtkMenuItem *item, gpointer data) { PurpleAccount *account = PURPLE_ACCOUNT(data); purple_account_set_enabled(account, PIDGIN_UI, TRUE); } /****************************************************************************** * Helpers *****************************************************************************/ static GtkWidget * pidgin_accounts_menu_create_account_menu_item(PidginAccountsMenu *menu, PurpleAccount *account) { GtkWidget *item = NULL; const gchar *account_name = purple_account_get_username(account); const gchar *protocol_name = purple_account_get_protocol_name(account); gchar *label = g_strdup_printf("%s (%s)", account_name, protocol_name); item = gtk_menu_item_new_with_label(label); g_free(label); gtk_widget_show(item); return item; } static void pidgin_accounts_menu_add_enabled_account(PidginAccountsMenu *menu, PurpleAccount *account) { GtkWidget *item = NULL, *submenu = NULL; /* if the account is in the disabled list, delete its widget */ if (g_hash_table_lookup_extended(menu->disabled_items, account, NULL, &item)) { g_clear_pointer(&item, gtk_widget_destroy); g_hash_table_remove(menu->disabled_items, account); } item = pidgin_accounts_menu_create_account_menu_item(menu, account); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_hash_table_insert(menu->account_items, g_object_ref(G_OBJECT(account)), item); /* create the submenu and attach it to item right away, this allows us to * reuse item for the submenu items. */ submenu = pidgin_account_actions_menu_new(account); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); } static void pidgin_accounts_menu_add_disabled_account(PidginAccountsMenu *menu, PurpleAccount *account) { GtkWidget *item = NULL; /* if the account is in the enabled list, delete its widget */ if (g_hash_table_lookup_extended(menu->account_items, account, NULL, &item)) { g_clear_pointer(&item, gtk_widget_destroy); g_hash_table_remove(menu->account_items, account); } item = pidgin_accounts_menu_create_account_menu_item(menu, account); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(pidgin_accounts_menu_enable_account), account); gtk_menu_shell_append(GTK_MENU_SHELL(menu->disabled_menu), item); g_hash_table_insert(menu->disabled_items, g_object_ref(G_OBJECT(account)), item); } static void pidgin_accounts_menu_add_current(PidginAccountsMenu *menu) { GList *accounts = NULL, *l = NULL; accounts = purple_accounts_get_all(); for(l = accounts; l != NULL; l = l->next) { PurpleAccount *account = PURPLE_ACCOUNT(l->data); if(purple_account_get_enabled(account, PIDGIN_UI)) { pidgin_accounts_menu_add_enabled_account(menu, account); } else { pidgin_accounts_menu_add_disabled_account(menu, account); } } } /****************************************************************************** * Purple Signal Callbacks *****************************************************************************/ static void pidgin_accounts_menu_account_status_changed(PurpleAccount *account, gpointer d) { PidginAccountsMenu *menu = PIDGIN_ACCOUNTS_MENU(d); gpointer data = NULL; data = g_hash_table_lookup(menu->account_items, account); if(GTK_IS_WIDGET(data)) { gtk_menu_item_set_submenu(GTK_MENU_ITEM(data), pidgin_account_actions_menu_new(account)); } } static void pidgin_accounts_menu_account_enabled(PurpleAccount *account, gpointer data) { pidgin_accounts_menu_add_enabled_account(PIDGIN_ACCOUNTS_MENU(data), account); } static void pidgin_accounts_menu_account_disabled(PurpleAccount *account, gpointer data) { pidgin_accounts_menu_add_disabled_account(PIDGIN_ACCOUNTS_MENU(data), account); } /****************************************************************************** * GObject Implementation *****************************************************************************/ G_DEFINE_TYPE(PidginAccountsMenu, pidgin_accounts_menu, GTK_TYPE_MENU) static void pidgin_accounts_menu_init(PidginAccountsMenu *menu) { gpointer handle; /* initialize our template */ gtk_widget_init_template(GTK_WIDGET(menu)); /* create our storage for the items */ menu->account_items = g_hash_table_new_full(g_direct_hash, g_direct_equal, g_object_unref, NULL); menu->disabled_items = g_hash_table_new_full(g_direct_hash, g_direct_equal, g_object_unref, NULL); /* add all of the existing accounts */ pidgin_accounts_menu_add_current(menu); /* finally connect to the purple signals to stay up to date */ handle = purple_accounts_get_handle(); purple_signal_connect(handle, "account-signed-on", menu, G_CALLBACK(pidgin_accounts_menu_account_status_changed), menu); purple_signal_connect(handle, "account-signed-off", menu, G_CALLBACK(pidgin_accounts_menu_account_status_changed), menu); purple_signal_connect(handle, "account-actions-changed", menu, G_CALLBACK(pidgin_accounts_menu_account_status_changed), menu); purple_signal_connect(handle, "account-enabled", menu, G_CALLBACK(pidgin_accounts_menu_account_enabled), menu); purple_signal_connect(handle, "account-disabled", menu, G_CALLBACK(pidgin_accounts_menu_account_disabled), menu); }; static void pidgin_accounts_menu_finalize(GObject *obj) { PidginAccountsMenu *menu = PIDGIN_ACCOUNTS_MENU(obj); purple_signals_disconnect_by_handle(obj); g_hash_table_destroy(menu->account_items); g_hash_table_destroy(menu->disabled_items); G_OBJECT_CLASS(pidgin_accounts_menu_parent_class)->finalize(obj); } static void pidgin_accounts_menu_class_init(PidginAccountsMenuClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS(klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); obj_class->finalize = pidgin_accounts_menu_finalize; gtk_widget_class_set_template_from_resource( widget_class, "/im/pidgin/Pidgin/Accounts/menu.ui" ); gtk_widget_class_bind_template_child(widget_class, PidginAccountsMenu, disabled_menu); gtk_widget_class_bind_template_child(widget_class, PidginAccountsMenu, separator); gtk_widget_class_bind_template_callback(widget_class, pidgin_accounts_menu_open_manager_cb); } /****************************************************************************** * Public API *****************************************************************************/ GtkWidget * pidgin_accounts_menu_new(void) { return GTK_WIDGET(g_object_new(PIDGIN_TYPE_ACCOUNTS_MENU, NULL)); }