pidgin/pidgin

Split account display from chooser into its own widget

12 months ago, Elliott Sales de Andrade
3c481d9cc840
Parents cd96db566218
Children 6b2ba7253a36
Split account display from chooser into its own widget

This will allow re-using it elsewhere when we need to display the account.

Testing Done:
Compiled and opened Add a Buddy dialog, Room List, etc. that used the chooser.

Reviewed at https://reviews.imfreedom.org/r/2360/
--- a/pidgin/meson.build Mon Mar 20 21:22:53 2023 -0500
+++ b/pidgin/meson.build Mon Mar 20 22:25:54 2023 -0500
@@ -20,6 +20,7 @@
'libpidgin.c',
'pidginabout.c',
'pidginaccountchooser.c',
+ 'pidginaccountdisplay.c',
'pidginaccounteditor.c',
'pidginaccountfilterconnected.c',
'pidginaccountfilterprotocol.c',
@@ -87,6 +88,7 @@
'gtkxfer.h',
'pidginabout.h',
'pidginaccountchooser.h',
+ 'pidginaccountdisplay.h',
'pidginaccounteditor.h',
'pidginaccountfilterconnected.h',
'pidginaccountfilterprotocol.h',
--- a/pidgin/pidginaccountchooser.c Mon Mar 20 21:22:53 2023 -0500
+++ b/pidgin/pidginaccountchooser.c Mon Mar 20 22:25:54 2023 -0500
@@ -46,49 +46,6 @@
/******************************************************************************
* Callbacks
*****************************************************************************/
-static char *
-pidgin_account_chooser_icon_name_cb(G_GNUC_UNUSED GObject *self,
- PurpleAccount *account,
- G_GNUC_UNUSED gpointer data)
-{
- const char *icon_name = NULL;
-
- if(PURPLE_IS_ACCOUNT(account)) {
- PurpleProtocol *protocol = purple_account_get_protocol(account);
- icon_name = purple_protocol_get_icon_name(protocol);
- }
-
- return g_strdup(icon_name);
-}
-
-static char *
-pidgin_account_chooser_label_cb(G_GNUC_UNUSED GObject *self,
- PurpleAccount *account,
- G_GNUC_UNUSED gpointer data)
-{
- gchar *markup = NULL;
- const char *alias = NULL;
- const char *protocol_name = NULL;
- const char *username = NULL;
-
- if(!PURPLE_IS_ACCOUNT(account)) {
- return NULL;
- }
-
- alias = purple_contact_info_get_alias(PURPLE_CONTACT_INFO(account));
- protocol_name = purple_account_get_protocol_name(account);
- username = purple_contact_info_get_username(PURPLE_CONTACT_INFO(account));
-
- if(alias != NULL) {
- markup = g_strdup_printf(_("%s (%s) (%s)"), username, alias,
- protocol_name);
- } else {
- markup = g_strdup_printf(_("%s (%s)"), username, protocol_name);
- }
-
- return markup;
-}
-
static void
pidgin_account_chooser_changed_cb(G_GNUC_UNUSED GObject *obj,
G_GNUC_UNUSED GParamSpec *pspec,
@@ -175,10 +132,6 @@
filter);
gtk_widget_class_bind_template_callback(widget_class,
- pidgin_account_chooser_icon_name_cb);
- gtk_widget_class_bind_template_callback(widget_class,
- pidgin_account_chooser_label_cb);
- gtk_widget_class_bind_template_callback(widget_class,
pidgin_account_chooser_changed_cb);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountdisplay.c Mon Mar 20 22:25:54 2023 -0500
@@ -0,0 +1,199 @@
+/*
+ * 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-lib.h>
+
+#include <gtk/gtk.h>
+
+#include "pidginaccountdisplay.h"
+
+struct _PidginAccountDisplay {
+ GtkBox parent;
+
+ GtkImage *image;
+ GtkLabel *label;
+
+ PurpleAccount *account;
+};
+
+enum {
+ PROP_0,
+ PROP_ACCOUNT,
+ PROP_LAST
+};
+
+static GParamSpec *properties[PROP_LAST] = {NULL};
+
+/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+static void
+pidgin_account_display_refresh(PidginAccountDisplay *display) {
+ const char *icon_name = NULL;
+ char *markup = NULL;
+
+ if(PURPLE_IS_ACCOUNT(display->account)) {
+ PurpleAccount *account = display->account;
+ PurpleContactInfo *info = NULL;
+ PurpleProtocol *protocol = NULL;
+ const char *alias = NULL;
+ const char *protocol_name = NULL;
+ const char *username = NULL;
+
+ protocol = purple_account_get_protocol(account);
+ icon_name = purple_protocol_get_icon_name(protocol);
+
+ info = PURPLE_CONTACT_INFO(account);
+ alias = purple_contact_info_get_alias(info);
+ protocol_name = purple_account_get_protocol_name(account);
+ username = purple_contact_info_get_username(info);
+
+ if(alias != NULL) {
+ markup = g_strdup_printf(_("%s (%s) (%s)"), username, alias,
+ protocol_name);
+ } else {
+ markup = g_strdup_printf(_("%s (%s)"), username, protocol_name);
+ }
+ }
+
+ gtk_image_set_from_icon_name(display->image, icon_name);
+ gtk_label_set_text(display->label, markup);
+
+ g_free(markup);
+}
+
+/******************************************************************************
+ * GObject implementation
+ *****************************************************************************/
+G_DEFINE_TYPE(PidginAccountDisplay, pidgin_account_display, GTK_TYPE_BOX)
+
+static void
+pidgin_account_display_get_property(GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ PidginAccountDisplay *display = PIDGIN_ACCOUNT_DISPLAY(object);
+
+ switch (prop_id) {
+ case PROP_ACCOUNT:
+ g_value_set_object(value,
+ pidgin_account_display_get_account(display));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+pidgin_account_display_set_property(GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ PidginAccountDisplay *display = PIDGIN_ACCOUNT_DISPLAY(object);
+
+ switch (prop_id) {
+ case PROP_ACCOUNT:
+ pidgin_account_display_set_account(display,
+ g_value_get_object(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+pidgin_account_display_finalize(GObject *obj) {
+ PidginAccountDisplay *display = PIDGIN_ACCOUNT_DISPLAY(obj);
+
+ g_clear_object(&display->account);
+
+ G_OBJECT_CLASS(pidgin_account_display_parent_class)->finalize(obj);
+}
+
+
+static void
+pidgin_account_display_class_init(PidginAccountDisplayClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+ /* Properties */
+ obj_class->get_property = pidgin_account_display_get_property;
+ obj_class->set_property = pidgin_account_display_set_property;
+ obj_class->finalize = pidgin_account_display_finalize;
+
+ /**
+ * PurpleAccountDisplay:account:
+ *
+ * The account that is currently displayed.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_ACCOUNT] = g_param_spec_object(
+ "account", "Account", "The account that is currently displayed.",
+ PURPLE_TYPE_ACCOUNT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(obj_class, PROP_LAST, properties);
+
+ /* Widget template */
+ gtk_widget_class_set_template_from_resource(
+ widget_class, "/im/pidgin/Pidgin3/Accounts/display.ui");
+
+ gtk_widget_class_bind_template_child(widget_class, PidginAccountDisplay,
+ image);
+ gtk_widget_class_bind_template_child(widget_class, PidginAccountDisplay,
+ label);
+}
+
+static void
+pidgin_account_display_init(PidginAccountDisplay *display) {
+ gtk_widget_init_template(GTK_WIDGET(display));
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+GtkWidget *
+pidgin_account_display_new(PurpleAccount *account) {
+ return g_object_new(PIDGIN_TYPE_ACCOUNT_DISPLAY,
+ "account", account,
+ NULL);
+}
+
+PurpleAccount *
+pidgin_account_display_get_account(PidginAccountDisplay *display) {
+ g_return_val_if_fail(PIDGIN_IS_ACCOUNT_DISPLAY(display), NULL);
+
+ return display->account;
+}
+
+void
+pidgin_account_display_set_account(PidginAccountDisplay *display,
+ PurpleAccount *account)
+{
+ g_return_if_fail(PIDGIN_IS_ACCOUNT_DISPLAY(display));
+
+ if(g_set_object(&display->account, account)) {
+ pidgin_account_display_refresh(display);
+
+ g_object_notify_by_pspec(G_OBJECT(display), properties[PROP_ACCOUNT]);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountdisplay.h Mon Mar 20 22:25:54 2023 -0500
@@ -0,0 +1,78 @@
+/*
+ * 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_ACCOUNT_DISPLAY_H
+#define PIDGIN_ACCOUNT_DISPLAY_H
+
+#include <gtk/gtk.h>
+
+#include <purple.h>
+
+G_BEGIN_DECLS
+
+#define PIDGIN_TYPE_ACCOUNT_DISPLAY (pidgin_account_display_get_type())
+G_DECLARE_FINAL_TYPE(PidginAccountDisplay, pidgin_account_display, PIDGIN,
+ ACCOUNT_DISPLAY, GtkBox)
+
+/**
+ * pidgin_account_display_new:
+ * @account: The account to display.
+ *
+ * Creates a display for an account.
+ *
+ * Returns: (transfer full): The account display.
+ *
+ * Since: 3.0.0
+ */
+GtkWidget *pidgin_account_display_new(PurpleAccount *account);
+
+/**
+ * pidgin_account_display_get_account:
+ * @display: The display.
+ *
+ * Gets the currently displayed account.
+ *
+ * Returns: (transfer none): Returns the [type@Purple.Account] that is
+ * currently displayed.
+ *
+ * Since: 3.0.0
+ */
+PurpleAccount *pidgin_account_display_get_account(PidginAccountDisplay *display);
+
+/**
+ * pidgin_account_display_set_account:
+ * @display: The display.
+ * @account: The account to display.
+ *
+ * Sets the currently displayed account.
+ *
+ * Since: 3.0.0
+ */
+void pidgin_account_display_set_account(PidginAccountDisplay *display, PurpleAccount *account);
+
+G_END_DECLS
+
+#endif /* PIDGIN_ACCOUNT_DISPLAY_H */
--- a/pidgin/resources/Accounts/chooser.ui Mon Mar 20 21:22:53 2023 -0500
+++ b/pidgin/resources/Accounts/chooser.ui Mon Mar 20 22:25:54 2023 -0500
@@ -33,28 +33,10 @@
<interface>
<template class="GtkListItem">
<property name="child">
- <object class="GtkBox">
- <property name="orientation">horizontal</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkImage">
- <binding name="icon-name">
- <closure type="gchararray" function="pidgin_account_chooser_icon_name_cb">
- <lookup name="item">GtkListItem</lookup>
- </closure>
- </binding>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="xalign">0</property>
- <binding name="label">
- <closure type="gchararray" function="pidgin_account_chooser_label_cb">
- <lookup name="item">GtkListItem</lookup>
- </closure>
- </binding>
- </object>
- </child>
+ <object class="PidginAccountDisplay">
+ <binding name="account">
+ <lookup name="item">GtkListItem</lookup>
+ </binding>
</object>
</property>
</template>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/resources/Accounts/display.ui Mon Mar 20 22:25:54 2023 -0500
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Pidgin - Internet Messenger
+Copyright (C) Pidgin Developers <devel@pidgin.im>
+
+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 library; if not, see <https://www.gnu.org/licenses/>.
+-->
+<interface>
+ <requires lib="gtk" version="4.0"/>
+ <!-- interface-license-type gplv2 -->
+ <!-- interface-name Pidgin -->
+ <!-- interface-description Internet Messenger -->
+ <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
+ <template class="PidginAccountDisplay" parent="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage" id="image"></object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="xalign">0</property>
+ </object>
+ </child>
+ </template>
+</interface>
--- a/pidgin/resources/pidgin.gresource.xml Mon Mar 20 21:22:53 2023 -0500
+++ b/pidgin/resources/pidgin.gresource.xml Mon Mar 20 22:25:54 2023 -0500
@@ -6,6 +6,7 @@
<file compressed="true" preprocess="json-stripblanks">About/credits.json</file>
<file compressed="true" preprocess="xml-stripblanks">Accounts/account-row.ui</file>
<file compressed="true" preprocess="xml-stripblanks">Accounts/chooser.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks">Accounts/display.ui</file>
<file compressed="true" preprocess="xml-stripblanks">Accounts/editor.ui</file>
<file compressed="true" preprocess="xml-stripblanks">Accounts/manager.ui</file>
<file compressed="true" preprocess="xml-stripblanks">Avatar/avatar.ui</file>