Wed, 12 May 2021 05:36:35 -0500
Convert credentials page to use HdyPreferencesGroup and a list box.
* Convert credentials page to use `HdyPreferencesGroup` and a list box.
* Add widget for displaying a credential provider in a list box.
* Convert `PidginCredentialsPage` into `HdyPreferencesPage`.
Testing Done:
Opened Preferences, switch to Credentials page, and see/toggle selected provider.
Reviewed at https://reviews.imfreedom.org/r/644/
--- a/doc/reference/pidgin/pidgin-docs.xml Thu May 06 22:36:35 2021 -0500 +++ b/doc/reference/pidgin/pidgin-docs.xml Wed May 12 05:36:35 2021 -0500 @@ -64,6 +64,7 @@ <xi:include href="xml/pidgincontactlist.xml" /> <xi:include href="xml/pidginconversationwindow.xml" /> <xi:include href="xml/pidgincore.xml" /> + <xi:include href="xml/pidgincredentialproviderrow.xml" /> <xi:include href="xml/pidgincredentialproviderstore.xml" /> <xi:include href="xml/pidgincredentialspage.xml" /> <xi:include href="xml/pidgindebug.xml" />
--- a/meson.build Thu May 06 22:36:35 2021 -0500 +++ b/meson.build Wed May 12 05:36:35 2021 -0500 @@ -257,6 +257,7 @@ ####################################################################### if get_option('gtkui') gtk = dependency('gtk+-3.0', version : '>= 3.22.0') + libhandy = dependency('libhandy-1', version : '>= 1') talkatu_dep = dependency('talkatu', version: '>=0.1.0', required : false) if talkatu_dep.found()
--- a/pidgin/meson.build Thu May 06 22:36:35 2021 -0500 +++ b/pidgin/meson.build Wed May 12 05:36:35 2021 -0500 @@ -44,6 +44,7 @@ 'pidgincontactcompletion.c', 'pidginconversationwindow.c', 'pidgincontactlist.c', + 'pidgincredentialproviderrow.c', 'pidgincredentialproviderstore.c', 'pidgincredentialspage.c', 'pidgindebug.c', @@ -114,6 +115,7 @@ 'pidginconversationwindow.h', 'pidgincontactlist.h', 'pidgincore.h', + 'pidgincredentialproviderrow.h', 'pidgincredentialproviderstore.h', 'pidgincredentialspage.h', 'pidgindialog.h', @@ -216,6 +218,7 @@ gtk, IOKIT, json, + libhandy, math, nice, libsoup, @@ -248,7 +251,7 @@ include_directories : [toplevel_inc, libpidgin_inc], link_with : libpidgin, sources : libpidgin_built_headers, - dependencies : [gtk, glib, math, talkatu_dep, gplugin_gtk_dep]) + dependencies : [gtk, glib, libhandy, math, talkatu_dep, gplugin_gtk_dep]) pidgin = executable('pidgin3', pidgin_SOURCES,
--- a/pidgin/pidginapplication.c Thu May 06 22:36:35 2021 -0500 +++ b/pidgin/pidginapplication.c Wed May 12 05:36:35 2021 -0500 @@ -31,6 +31,8 @@ #include <gplugin.h> #include <purple.h> +#include <handy.h> + #include "pidginapplication.h" #include "gtkaccount.h" @@ -492,6 +494,7 @@ gpointer handle = NULL; G_APPLICATION_CLASS(pidgin_application_parent_class)->startup(application); + hdy_init(); /* set a user-specified config directory */ if (opt_config_dir_arg != NULL) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/pidgincredentialproviderrow.c Wed May 12 05:36:35 2021 -0500 @@ -0,0 +1,224 @@ +/* + * 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 <purple.h> + +#include <handy.h> + +#include "pidgincredentialproviderrow.h" + +struct _PidginCredentialProviderRow { + HdyActionRow parent; + + PurpleCredentialProvider *provider; + + GtkWidget *active; + GtkWidget *configure; +}; + +enum { + PROP_0, + PROP_PROVIDER, + PROP_ACTIVE, + N_PROPERTIES, +}; +static GParamSpec *properties[N_PROPERTIES] = {NULL, }; + +G_DEFINE_TYPE(PidginCredentialProviderRow, pidgin_credential_provider_row, + HDY_TYPE_ACTION_ROW) + +/****************************************************************************** + * Helpers + *****************************************************************************/ +static void +pidgin_credential_provider_row_set_provider(PidginCredentialProviderRow *row, + PurpleCredentialProvider *provider) +{ + if(!g_set_object(&row->provider, provider)) { + return; + } + + if(PURPLE_IS_CREDENTIAL_PROVIDER(provider)) { + hdy_preferences_row_set_title( + HDY_PREFERENCES_ROW(row), + purple_credential_provider_get_name(provider)); + hdy_action_row_set_subtitle( + HDY_ACTION_ROW(row), + purple_credential_provider_get_description(provider)); + /* Not implemented yet, so always hide the configure button. */ + gtk_widget_set_visible(row->configure, FALSE); + } + + /* Notify that we changed. */ + g_object_notify_by_pspec(G_OBJECT(row), properties[PROP_PROVIDER]); +} + + +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +static void +pidgin_credential_provider_row_get_property(GObject *obj, guint param_id, + GValue *value, GParamSpec *pspec) +{ + PidginCredentialProviderRow *row = PIDGIN_CREDENTIAL_PROVIDER_ROW(obj); + + switch(param_id) { + case PROP_PROVIDER: + g_value_set_object(value, + pidgin_credential_provider_row_get_provider(row)); + break; + case PROP_ACTIVE: + g_value_set_boolean(value, + pidgin_credential_provider_row_get_active(row)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); + break; + } +} + +static void +pidgin_credential_provider_row_set_property(GObject *obj, guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + PidginCredentialProviderRow *row = PIDGIN_CREDENTIAL_PROVIDER_ROW(obj); + + switch(param_id) { + case PROP_PROVIDER: + pidgin_credential_provider_row_set_provider(row, + g_value_get_object(value)); + break; + case PROP_ACTIVE: + pidgin_credential_provider_row_set_active(row, + g_value_get_boolean(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); + break; + } +} + +static void +pidgin_credential_provider_row_finalize(GObject *obj) +{ + PidginCredentialProviderRow *row = PIDGIN_CREDENTIAL_PROVIDER_ROW(obj); + + g_clear_object(&row->provider); +} + +static void +pidgin_credential_provider_row_init(PidginCredentialProviderRow *row) +{ + gtk_widget_init_template(GTK_WIDGET(row)); + + /* If this row is active, then enable the provider properties button (which + * may or may not be visible). */ + g_object_bind_property(G_OBJECT(row), "active", + G_OBJECT(row->configure), "sensitive", + G_BINDING_DEFAULT); +} + +static void +pidgin_credential_provider_row_class_init(PidginCredentialProviderRowClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + + obj_class->get_property = pidgin_credential_provider_row_get_property; + obj_class->set_property = pidgin_credential_provider_row_set_property; + obj_class->finalize = pidgin_credential_provider_row_finalize; + + /** + * PidginCredentialProviderRow::provider + * + * The #PurpleCredentialProvider whose information will be displayed. + */ + properties[PROP_PROVIDER] = g_param_spec_object( + "provider", "provider", + "The PurpleCredentialProvider instance", + PURPLE_TYPE_CREDENTIAL_PROVIDER, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + /** + * PidginCredentialProviderRow::active + * + * Whether the #PurpleCredentialProvider is currently active. + */ + properties[PROP_ACTIVE] = g_param_spec_boolean( + "active", "active", + "Whether the PurpleCredentialProvider is active", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(obj_class, N_PROPERTIES, properties); + + gtk_widget_class_set_template_from_resource( + widget_class, + "/im/pidgin/Pidgin/Prefs/credentialprovider.ui" + ); + + gtk_widget_class_bind_template_child(widget_class, + PidginCredentialProviderRow, + active); + gtk_widget_class_bind_template_child(widget_class, + PidginCredentialProviderRow, + configure); +} + +/****************************************************************************** + * API + *****************************************************************************/ +GtkWidget * +pidgin_credential_provider_row_new(PurpleCredentialProvider *provider) { + g_return_val_if_fail(PURPLE_IS_CREDENTIAL_PROVIDER(provider), NULL); + + return GTK_WIDGET(g_object_new(PIDGIN_TYPE_CREDENTIAL_PROVIDER_ROW, + "provider", provider, + NULL)); +} + +PurpleCredentialProvider * +pidgin_credential_provider_row_get_provider(PidginCredentialProviderRow *row) { + g_return_val_if_fail(PIDGIN_IS_CREDENTIAL_PROVIDER_ROW(row), NULL); + + return row->provider; +} + +gboolean +pidgin_credential_provider_row_get_active(PidginCredentialProviderRow *row) { + g_return_val_if_fail(PIDGIN_IS_CREDENTIAL_PROVIDER_ROW(row), FALSE); + + return gtk_widget_get_visible(row->active); +} + +void +pidgin_credential_provider_row_set_active(PidginCredentialProviderRow *row, + gboolean active) +{ + g_return_if_fail(PIDGIN_IS_CREDENTIAL_PROVIDER_ROW(row)); + + gtk_widget_set_visible(row->active, active); + + g_object_notify_by_pspec(G_OBJECT(row), properties[PROP_ACTIVE]); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/pidgincredentialproviderrow.h Wed May 12 05:36:35 2021 -0500 @@ -0,0 +1,94 @@ +/* + * 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_CREDENTIAL_PROVIDER_ROW_H +#define PIDGIN_CREDENTIAL_PROVIDER_ROW_H + +/** + * SECTION:pidgincredentialproviderrow + * @section_id: pidgin-pidgincredentialproviderrow + * @short_description: The preferences widget for a credential provider. + * @title: Credential provider widget + * + * #PidginCredentialProviderRow is a widget for the preferences window to let + * users configure their credential provider. + */ + +#include <glib.h> + +#include <gtk/gtk.h> + +#include <handy.h> + +G_BEGIN_DECLS + +#define PIDGIN_TYPE_CREDENTIAL_PROVIDER_ROW (pidgin_credential_provider_row_get_type()) +G_DECLARE_FINAL_TYPE(PidginCredentialProviderRow, + pidgin_credential_provider_row, + PIDGIN, CREDENTIAL_PROVIDER_ROW, HdyActionRow) + +/** + * pidgin_credential_provider_row_new: + * @provider: The credential provider to bind. + * + * Creates a new #PidginCredentialProviderRow instance. + * + * Returns: (transfer full): The new #PidginCredentialProviderRow instance. + */ +GtkWidget *pidgin_credential_provider_row_new(PurpleCredentialProvider *provider); + +/** + * pidgin_credential_provider_row_get_provider: + * @row: The row instance. + * + * Gets the #PurpleCredentialProvider displayed by this widget. + * + * Returns: (transfer none): The displayed #PurpleCredentialProvider. + */ +PurpleCredentialProvider *pidgin_credential_provider_row_get_provider(PidginCredentialProviderRow *row); + +/** + * pidgin_credential_provider_row_get_active: + * @row: The row instance. + * + * Gets whether the row is displayed as active. + * + * Returns: Whether the row is active. + */ +gboolean pidgin_credential_provider_row_get_active(PidginCredentialProviderRow *row); + +/** + * pidgin_credential_provider_row_set_active: + * @row: The row instance. + * @active: Whether to display as active. + * + * Sets whether the row is displayed as active. + */ +void pidgin_credential_provider_row_set_active(PidginCredentialProviderRow *row, gboolean active); + +G_END_DECLS + +#endif /* PIDGIN_CREDENTIAL_PROVIDER_ROW_H */
--- a/pidgin/pidgincredentialspage.c Thu May 06 22:36:35 2021 -0500 +++ b/pidgin/pidgincredentialspage.c Wed May 12 05:36:35 2021 -0500 @@ -22,95 +22,114 @@ #include <purple.h> +#include <handy.h> + #include "pidgincredentialspage.h" -#include "pidgincredentialproviderstore.h" +#include "pidgincredentialproviderrow.h" struct _PidginCredentialsPage { - GtkBox parent; + HdyPreferencesPage parent; - GtkWidget *combo; - GtkCellRenderer *renderer; + GtkWidget *credential_list; }; G_DEFINE_TYPE(PidginCredentialsPage, pidgin_credentials_page, - GTK_TYPE_BOX) + HDY_TYPE_PREFERENCES_PAGE) /****************************************************************************** * Helpers *****************************************************************************/ static void -pidgin_credentials_page_combo_changed_cb(GtkComboBox *widget, gpointer data) { - PidginCredentialsPage *page = PIDGIN_CREDENTIALS_PAGE(data); - GtkTreeIter iter; +pidgin_credentials_page_create_row(PurpleCredentialProvider *provider, + gpointer data) +{ + GtkListBox *box = GTK_LIST_BOX(data); + GtkWidget *row = NULL; + + row = pidgin_credential_provider_row_new(provider); + gtk_list_box_prepend(box, row); +} - if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(page->combo), &iter)) { - PurpleCredentialManager *manager = NULL; - GError *error = NULL; - GtkTreeModel *model = NULL; - gchar *id = NULL; +static gint +pidgin_credentials_page_sort_rows(GtkListBoxRow *row1, GtkListBoxRow *row2, + G_GNUC_UNUSED gpointer user_data) +{ + PidginCredentialProviderRow *pcprow = NULL; + PurpleCredentialProvider *provider = NULL; + const gchar *id1 = NULL; + gboolean is_noop1 = FALSE; + const gchar *id2 = NULL; + gboolean is_noop2 = FALSE; - model = gtk_combo_box_get_model(GTK_COMBO_BOX(page->combo)); + pcprow = PIDGIN_CREDENTIAL_PROVIDER_ROW(row1); + provider = pidgin_credential_provider_row_get_provider(pcprow); + id1 = purple_credential_provider_get_id(provider); + is_noop1 = purple_strequal(id1, "noop-provider"); - gtk_tree_model_get(model, &iter, - PIDGIN_CREDENTIAL_PROVIDER_STORE_COLUMN_ID, &id, - -1); + pcprow = PIDGIN_CREDENTIAL_PROVIDER_ROW(row2); + provider = pidgin_credential_provider_row_get_provider(pcprow); + id2 = purple_credential_provider_get_id(provider); + is_noop2 = purple_strequal(id2, "noop-provider"); - manager = purple_credential_manager_get_default(); - if(purple_credential_manager_set_active_provider(manager, id, &error)) { - purple_prefs_set_string("/purple/credentials/active-provider", id); - - g_free(id); - - return; - } + /* Sort None provider after everything else. */ + if (is_noop1 && is_noop2) { + return 0; + } else if (is_noop1 && !is_noop2) { + return 1; + } else if (!is_noop1 && is_noop2) { + return -1; + } + /* Sort normally by ID. */ + return g_strcmp0(id1, id2); +} - purple_debug_warning("credentials-page", "failed to set the active " - "credential provider to '%s': %s", - id, - error ? error->message : "unknown error"); +static void +pidgin_credential_page_list_row_activated_cb(GtkListBox *box, + GtkListBoxRow *row, + G_GNUC_UNUSED gpointer data) +{ + PurpleCredentialManager *manager = NULL; + PurpleCredentialProvider *provider = NULL; + const gchar *id = NULL; + GError *error = NULL; - g_free(id); - g_clear_error(&error); + provider = pidgin_credential_provider_row_get_provider( + PIDGIN_CREDENTIAL_PROVIDER_ROW(row)); + id = purple_credential_provider_get_id(provider); + + manager = purple_credential_manager_get_default(); + if(purple_credential_manager_set_active_provider(manager, id, &error)) { + purple_prefs_set_string("/purple/credentials/active-provider", id); + + return; } + + purple_debug_warning("credentials-page", "failed to set the active " + "credential provider to '%s': %s", + id, error ? error->message : "unknown error"); + + g_clear_error(&error); } static void pidgin_credentials_page_set_active_provider(PidginCredentialsPage *page, const gchar *new_id) { - GtkTreeIter iter; - GtkTreeModel *model = NULL; - - model = gtk_combo_box_get_model(GTK_COMBO_BOX(page->combo)); - - if(gtk_tree_model_get_iter_first(model, &iter)) { - do { - gchar *id = NULL; - - gtk_tree_model_get(model, &iter, - PIDGIN_CREDENTIAL_PROVIDER_STORE_COLUMN_ID, &id, - -1); + GList *rows = NULL; - if(purple_strequal(new_id, id)) { - g_signal_handlers_block_by_func(page->combo, - pidgin_credentials_page_combo_changed_cb, - page); - - gtk_combo_box_set_active_iter(GTK_COMBO_BOX(page->combo), - &iter); + rows = gtk_container_get_children(GTK_CONTAINER(page->credential_list)); + for (; rows; rows = g_list_delete_link(rows, rows)) { + PidginCredentialProviderRow *row = NULL; + PurpleCredentialProvider *provider = NULL; + const gchar *id = NULL; - g_signal_handlers_unblock_by_func(page->combo, - pidgin_credentials_page_combo_changed_cb, - page); - - g_free(id); + row = PIDGIN_CREDENTIAL_PROVIDER_ROW(rows->data); + provider = pidgin_credential_provider_row_get_provider(row); + id = purple_credential_provider_get_id(provider); - return; - } - - g_free(id); - } while(gtk_tree_model_iter_next(model, &iter)); + pidgin_credential_provider_row_set_active(row, + purple_strequal(new_id, id)); } } @@ -126,7 +145,7 @@ } /****************************************************************************** - * GObjectImplementation + * GObject Implementation *****************************************************************************/ static void pidgin_credentials_page_finalize(GObject *obj) { @@ -137,30 +156,26 @@ static void pidgin_credentials_page_init(PidginCredentialsPage *page) { + PurpleCredentialManager *manager = NULL; const gchar *active = NULL; gtk_widget_init_template(GTK_WIDGET(page)); - /* Set some constant properties on the renderer. This stuff is kind of - * dodgy, but it does stop the dialog from growing to fit a long - * description. - */ - g_object_set(G_OBJECT(page->renderer), - "width-chars", 40, - "wrap-mode", PANGO_WRAP_WORD_CHAR, - NULL); - purple_prefs_add_none("/purple/credentials"); purple_prefs_add_string("/purple/credentials/active-provider", NULL); + manager = purple_credential_manager_get_default(); + purple_credential_manager_foreach_provider( + manager, + pidgin_credentials_page_create_row, + page->credential_list); + gtk_list_box_set_sort_func(GTK_LIST_BOX(page->credential_list), + pidgin_credentials_page_sort_rows, NULL, NULL); + purple_prefs_connect_callback(page, "/purple/credentials/active-provider", pidgin_credentials_page_active_provider_changed_cb, page); - g_signal_connect(G_OBJECT(page->combo), "changed", - G_CALLBACK(pidgin_credentials_page_combo_changed_cb), - page); - active = purple_prefs_get_string("/purple/credentials/active-provider"); if(active != NULL) { pidgin_credentials_page_set_active_provider(page, active); @@ -180,9 +195,9 @@ ); gtk_widget_class_bind_template_child(widget_class, PidginCredentialsPage, - combo); - gtk_widget_class_bind_template_child(widget_class, PidginCredentialsPage, - renderer); + credential_list); + gtk_widget_class_bind_template_callback(widget_class, + pidgin_credential_page_list_row_activated_cb); } /******************************************************************************
--- a/pidgin/pidgincredentialspage.h Thu May 06 22:36:35 2021 -0500 +++ b/pidgin/pidgincredentialspage.h Wed May 12 05:36:35 2021 -0500 @@ -40,12 +40,13 @@ #include <glib.h> #include <gtk/gtk.h> +#include <handy.h> G_BEGIN_DECLS #define PIDGIN_TYPE_CREDENTIALS_PAGE (pidgin_credentials_page_get_type()) G_DECLARE_FINAL_TYPE(PidginCredentialsPage, pidgin_credentials_page, - PIDGIN, CREDENTIALS_PAGE, GtkBox) + PIDGIN, CREDENTIALS_PAGE, HdyPreferencesPage) /** * pidgin_credentials_page_new:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/resources/Prefs/credentialprovider.ui Wed May 12 05:36:35 2021 -0500 @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.38.2 + +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 program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +--> +<interface> + <requires lib="gtk+" version="3.22"/> + <requires lib="libhandy" version="0.0"/> + <!-- interface-license-type gplv2 --> + <!-- interface-name Pidgin --> + <!-- interface-description Internet Messenger --> + <!-- interface-copyright Pidgin Developers <devel@pidgin.im> --> + <object class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">document-properties-symbolic</property> + </object> + <template class="PidginCredentialProviderRow" parent="HdyActionRow"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="activatable">True</property> + <child> + <object class="GtkButton" id="configure"> + <property name="sensitive">False</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="image">image1</property> + <style> + <class name="circular"/> + </style> + </object> + </child> + <child> + <object class="GtkImage" id="active"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="valign">center</property> + <property name="xpad">6</property> + <property name="ypad">6</property> + <property name="icon-name">emblem-default-symbolic</property> + </object> + </child> + </template> +</interface>
--- a/pidgin/resources/Prefs/credentials.ui Thu May 06 22:36:35 2021 -0500 +++ b/pidgin/resources/Prefs/credentials.ui Wed May 12 05:36:35 2021 -0500 @@ -21,80 +21,33 @@ --> <interface> <requires lib="gtk+" version="3.22"/> - <requires lib="pidgin" version="3.0"/> + <requires lib="libhandy" version="0.0"/> <!-- interface-license-type gplv2 --> <!-- interface-name Pidgin --> <!-- interface-description Internet Messenger --> <!-- interface-copyright Pidgin Developers <devel@pidgin.im> --> - <object class="PidginCredentialProviderStore" id="store"/> - <template class="PidginCredentialsPage" parent="GtkBox"> + <template class="PidginCredentialsPage" parent="HdyPreferencesPage"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="border-width">12</property> - <property name="orientation">vertical</property> - <property name="spacing">18</property> + <property name="title" translatable="yes">Credentials</property> <child> - <object class="GtkFrame"> + <object class="HdyPreferencesGroup"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label-xalign">0</property> - <property name="shadow-type">none</property> + <property name="description" translatable="yes">Pidgin does not store passwords directly, but uses the provider selected below to store passwords. Changing providers will not migrate existing stored passwords.</property> + <property name="title" translatable="yes">Credential Provider</property> <child> - <object class="GtkBox"> + <object class="GtkListBox" id="credential_list"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="margin-start">12</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="label" translatable="yes">Provider:</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="combo"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="model">store</property> - <child> - <object class="GtkCellRendererText" id="renderer"/> - <attributes> - <attribute name="markup">1</attribute> - </attributes> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="margin-bottom">6</property> - <property name="label" translatable="yes">Credential Provider</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> + <property name="selection-mode">none</property> + <signal name="row-activated" handler="pidgin_credential_page_list_row_activated_cb" after="yes" swapped="no"/> + <style> + <class name="content"/> + </style> </object> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> </child> </template> </interface>
--- a/pidgin/resources/Prefs/prefs.ui Thu May 06 22:36:35 2021 -0500 +++ b/pidgin/resources/Prefs/prefs.ui Wed May 12 05:36:35 2021 -0500 @@ -2467,8 +2467,6 @@ <object class="PidginCredentialsPage"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">18</property> <child> <placeholder/> </child>
--- a/pidgin/resources/pidgin.gresource.xml Thu May 06 22:36:35 2021 -0500 +++ b/pidgin/resources/pidgin.gresource.xml Wed May 12 05:36:35 2021 -0500 @@ -24,6 +24,7 @@ <file compressed="true">Plugins/dialog.ui</file> <file compressed="true">Plugins/menu.ui</file> <file compressed="true">Prefs/credentials.ui</file> + <file compressed="true">Prefs/credentialprovider.ui</file> <file compressed="true">Prefs/ip.css</file> <file compressed="true">Prefs/prefs.ui</file> <file compressed="true">Prefs/vv.ui</file>
--- a/po/POTFILES.in Thu May 06 22:36:35 2021 -0500 +++ b/po/POTFILES.in Wed May 12 05:36:35 2021 -0500 @@ -353,6 +353,7 @@ pidgin/pidgincontactcompletion.c pidgin/pidgincontactlist.c pidgin/pidginconversationwindow.c +pidgin/pidgincredentialproviderrow.c pidgin/pidgincredentialproviderstore.c pidgin/pidgincredentialspage.c pidgin/pidgindebug.c @@ -409,6 +410,7 @@ pidgin/resources/Plugins/dialog.ui pidgin/resources/Plugins/menu.ui pidgin/resources/Prefs/credentials.ui +pidgin/resources/Prefs/credentialprovider.ui pidgin/resources/Prefs/prefs.ui pidgin/resources/Prefs/vv.ui pidgin/resources/Privacy/dialog.ui