pidgin/pidgin

Parents 4960320545ef
Children 4a8bdbae8d8b
Create a menu controller that will keep a GMenu in sync with the disabled accounts in libpurple

Testing Done:
Used the account manager to disable and account, then disabled it from the menu and verified that the item was removed.

Reviewed at https://reviews.imfreedom.org/r/1326/
--- a/libpurple/purpleaccountmanager.c Sun Mar 13 23:59:40 2022 -0500
+++ b/libpurple/purpleaccountmanager.c Mon Mar 14 01:18:18 2022 -0500
@@ -251,6 +251,26 @@
}
PurpleAccount *
+purple_account_manager_find_by_id(PurpleAccountManager *manager,
+ const gchar *id)
+{
+ GList *l = NULL;
+
+ g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
+ g_return_val_if_fail(id != NULL, NULL);
+
+ for(l = manager->accounts; l != NULL; l = l->next) {
+ PurpleAccount *account = PURPLE_ACCOUNT(l->data);
+
+ if(purple_strequal(purple_account_get_id(account), id)) {
+ return account;
+ }
+ }
+
+ return NULL;
+}
+
+PurpleAccount *
purple_account_manager_find(PurpleAccountManager *manager,
const gchar *username, const gchar *protocol_id)
{
--- a/libpurple/purpleaccountmanager.h Sun Mar 13 23:59:40 2022 -0500
+++ b/libpurple/purpleaccountmanager.h Mon Mar 14 01:18:18 2022 -0500
@@ -126,6 +126,19 @@
GList *purple_account_manager_get_active(PurpleAccountManager *manager);
/**
+ * purple_account_manager_find_by_id:
+ * @manager: The account manager instance.
+ * @id: The id of the account.
+ *
+ * Looks up an account based on its id property.
+ *
+ * Returns: (transfer none): The account if found, otherwise %NULL.
+ *
+ * Since: 3.0.0
+ */
+PurpleAccount *purple_account_manager_find_by_id(PurpleAccountManager *manager, const gchar *id);
+
+/**
* purple_account_manager_find:
* @manager: The account manager instance.
* @username: The username of the account.
--- a/pidgin/meson.build Sun Mar 13 23:59:40 2022 -0500
+++ b/pidgin/meson.build Mon Mar 14 01:18:18 2022 -0500
@@ -23,6 +23,7 @@
'pidginaccountchooser.c',
'pidginaccountfilterconnected.c',
'pidginaccountfilterprotocol.c',
+ 'pidginaccountsdisabledmenu.c',
'pidginaccountsmenu.c',
'pidginaccountstore.c',
'pidginactiongroup.c',
@@ -85,6 +86,7 @@
'pidginaccountchooser.h',
'pidginaccountfilterconnected.h',
'pidginaccountfilterprotocol.h',
+ 'pidginaccountsdisabledmenu.h',
'pidginaccountsmenu.h',
'pidginaccountstore.h',
'pidginactiongroup.h',
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountsdisabledmenu.c Mon Mar 14 01:18:18 2022 -0500
@@ -0,0 +1,126 @@
+/*
+ * 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"
+
+#include "pidgincore.h"
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+pidgin_accounts_disabled_menu_refresh_helper(PurpleAccount *account,
+ gpointer data)
+{
+ GMenu *menu = data;
+
+ if(!purple_account_get_enabled(account, PIDGIN_UI)) {
+ gchar *label = NULL, *action = NULL;
+ const gchar *account_name = purple_account_get_username(account);
+ const gchar *protocol_name = purple_account_get_protocol_name(account);
+
+ /* translators: This format string is intended to contain the account
+ * name followed by the protocol name to uniquely identify a specific
+ * account.
+ */
+ label = g_strdup_printf(_("%s (%s)"), account_name, protocol_name);
+ action = g_strdup_printf("app.enable-account::%s",
+ purple_account_get_id(account));
+
+ g_menu_append(menu, label, action);
+
+ g_free(label);
+ g_free(action);
+ }
+}
+
+static void
+pidgin_accounts_disabled_menu_refresh(GMenu *menu) {
+ PurpleAccountManager *manager = NULL;
+
+ g_menu_remove_all(menu);
+
+ manager = purple_account_manager_get_default();
+ purple_account_manager_foreach(manager,
+ pidgin_accounts_disabled_menu_refresh_helper,
+ menu);
+
+ if(g_menu_model_get_n_items(G_MENU_MODEL(menu)) == 0) {
+ g_menu_append(menu, _("No disabled accounts"), "disabled");
+ }
+}
+
+/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+static void
+pidgin_accounts_disabled_menu_enabled_cb(G_GNUC_UNUSED PurpleAccount *account,
+ gpointer data)
+{
+ pidgin_accounts_disabled_menu_refresh(data);
+}
+
+static void
+pidgin_accounts_disabled_menu_disabled_cb(G_GNUC_UNUSED PurpleAccount *account,
+ gpointer data)
+{
+ pidgin_accounts_disabled_menu_refresh(data);
+}
+
+static void
+pidgin_accounts_disabled_menu_weak_notify_cb(G_GNUC_UNUSED gpointer data,
+ GObject *obj)
+{
+ purple_signals_disconnect_by_handle(obj);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+GMenu *
+pidgin_accounts_disabled_menu_new(void) {
+ GMenu *menu = NULL;
+ gpointer handle = NULL;
+
+ /* Create the menu and set our instance as data on it so it'll be freed
+ * when the menu is destroyed.
+ */
+ menu = g_menu_new();
+ g_object_weak_ref(G_OBJECT(menu),
+ pidgin_accounts_disabled_menu_weak_notify_cb, NULL);
+
+ /* Populate ourselves with any accounts that are already disabled. */
+ pidgin_accounts_disabled_menu_refresh(menu);
+
+ /* Wire up the purple signals we care about. */
+ handle = purple_accounts_get_handle();
+ purple_signal_connect(handle, "account-enabled", menu,
+ G_CALLBACK(pidgin_accounts_disabled_menu_enabled_cb),
+ menu);
+ purple_signal_connect(handle, "account-disabled", menu,
+ G_CALLBACK(pidgin_accounts_disabled_menu_disabled_cb),
+ menu);
+
+ return menu;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountsdisabledmenu.h Mon Mar 14 01:18:18 2022 -0500
@@ -0,0 +1,51 @@
+/*
+ * 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/>.
+ */
+
+#if !defined(PIDGIN_GLOBAL_HEADER_INSIDE) && !defined(PIDGIN_COMPILATION)
+# error "only <pidgin.h> may be included directly"
+#endif
+
+#ifndef PIDGIN_ACCOUNTS_DISABLED_MENU_H
+#define PIDGIN_ACCOUNTS_DISABLED_MENU_H
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <purple.h>
+
+G_BEGIN_DECLS
+
+/**
+ * pidgin_accounts_disabled_menu_new:
+ *
+ * Creates a [class@Gio.Menu] that will automatically update itself to include
+ * accounts that are disabled in libpurple.
+ *
+ * Returns: (transfer full): The new menu instance.
+ *
+ * Since: 3.0.0
+ */
+GMenu *pidgin_accounts_disabled_menu_new(void);
+
+G_END_DECLS
+
+#endif /* PIDGIN_ACCOUNTS_DISABLED_MENU_H */
\ No newline at end of file
--- a/pidgin/pidginapplication.c Sun Mar 13 23:59:40 2022 -0500
+++ b/pidgin/pidginapplication.c Mon Mar 14 01:18:18 2022 -0500
@@ -43,6 +43,7 @@
#include "gtksavedstatuses.h"
#include "gtkxfer.h"
#include "pidginabout.h"
+#include "pidginaccountsdisabledmenu.h"
#include "pidginconversationwindow.h"
#include "pidgincore.h"
#include "pidgindebug.h"
@@ -125,6 +126,18 @@
purple_plugins_refresh();
}
+static void
+pidgin_application_populate_dynamic_menus(PidginApplication *application) {
+ GMenu *target = NULL;
+ GMenuModel *source = NULL;
+
+ /* Link the AccountsDisabledMenu into its proper location. */
+ target = gtk_application_get_menu_by_id(GTK_APPLICATION(application),
+ "disabled-accounts");
+ source = pidgin_accounts_disabled_menu_new();
+ g_menu_append_section(target, NULL, source);
+}
+
/******************************************************************************
* Actions
*****************************************************************************/
@@ -245,6 +258,26 @@
}
static void
+pidgin_application_enable_account(GSimpleAction *simple, GVariant *parameter,
+ gpointer data)
+{
+ PurpleAccount *account = NULL;
+ PurpleAccountManager *manager = NULL;
+ const gchar *id = NULL;
+
+ id = g_variant_get_string(parameter, NULL);
+
+ manager = purple_account_manager_get_default();
+
+ account = purple_account_manager_find_by_id(manager, id);
+ if(PURPLE_IS_ACCOUNT(account)) {
+ if(!purple_account_get_enabled(account, PIDGIN_UI)) {
+ purple_account_set_enabled(account, PIDGIN_UI, TRUE);
+ }
+ }
+}
+
+static void
pidgin_application_file_transfers(GSimpleAction *simple, GVariant *parameter,
gpointer data)
{
@@ -352,6 +385,10 @@
.name = "debug",
.activate = pidgin_application_debug,
}, {
+ .name = "enable-account",
+ .activate = pidgin_application_enable_account,
+ .parameter_type = "s",
+ }, {
.name = "file-transfers",
.activate = pidgin_application_file_transfers,
}, {
@@ -630,6 +667,9 @@
g_list_free(active_accounts);
}
+ /* Populate our dynamic menus. */
+ pidgin_application_populate_dynamic_menus(PIDGIN_APPLICATION(application));
+
/* GTK clears the notification for us when opening the first window, but we
* may have launched with only a status icon, so clear it just in case.
*/
--- a/pidgin/resources/gtk/menus.ui Sun Mar 13 23:59:40 2022 -0500
+++ b/pidgin/resources/gtk/menus.ui Mon Mar 14 01:18:18 2022 -0500
@@ -184,9 +184,7 @@
<submenu>
<attribute name="label" translatable="yes">_Enable Account</attribute>
- <section>
- <attribute name="id">disabled-accounts</attribute>
- </section>
+ <section id="disabled-accounts"/>
</submenu>
</section>
<section>
--- a/po/POTFILES.in Sun Mar 13 23:59:40 2022 -0500
+++ b/po/POTFILES.in Mon Mar 14 01:18:18 2022 -0500
@@ -336,6 +336,7 @@
pidgin/pidginaccountchooser.c
pidgin/pidginaccountfilterconnected.c
pidgin/pidginaccountfilterprotocol.c
+pidgin/pidginaccountsdisabledmenu.c
pidgin/pidginaccountsmenu.c
pidgin/pidginaccountstore.c
pidgin/pidginactiongroup.c