pidgin/pidgin

68c7ef6c5320
Parents 648527ab9ae3
Children 0cf92aa817fd
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