pidgin/pidgin

Split keypad into its own widget

21 months ago, Elliott Sales de Andrade
27d70d93355d
Parents 34907838c401
Children 3d2e114380f6
Split keypad into its own widget

Testing Done:
Temporarily added a `GtkMenuButton` with a `GtkPopover` containing this widget to the media window, so I could check the buttons. Not sure that it totally works in the final window as I didn't start a real media session.

```
diff --git a/pidgin/gtkmedia.c b/pidgin/gtkmedia.c
--- a/pidgin/gtkmedia.c
+++ b/pidgin/gtkmedia.c
@@ -261,6 +261,14 @@
}

static void
+pidgin_media_dtmf_key_pressed_debug_cb(G_GNUC_UNUSED PidginKeypad *keypad,
+ gchar num,
+ G_GNUC_UNUSED gpointer data)
+{
+ g_message("DTMF key pressed! %c", num);
+}
+
+static void
pidgin_media_init (PidginMedia *media)
{
GtkWidget *vbox;
@@ -289,6 +297,27 @@
gtk_box_pack_start(GTK_BOX(vbox), media->priv->display, TRUE, TRUE, 6);
gtk_widget_show(vbox);

+ {
+ GtkWidget *button = NULL;
+ GtkWidget *keypad = NULL;
+ GtkWidget *popover = NULL;
+
+ button = gtk_menu_button_new();
+ popover = gtk_popover_new(button);
+ gtk_menu_button_set_popover(GTK_MENU_BUTTON(button), popover);
+
+ keypad = pidgin_keypad_new();
+ pidgin_keypad_set_key_capture_widget(PIDGIN_KEYPAD(keypad),
+ GTK_WIDGET(media));
+ g_signal_connect(keypad, "pressed",
+ G_CALLBACK(pidgin_media_dtmf_key_pressed_debug_cb),
+ NULL);
+ gtk_container_add(GTK_CONTAINER(popover), keypad);
+
+ gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+ gtk_widget_show(button);
+ }
+
g_signal_connect(G_OBJECT(media), "delete-event",
G_CALLBACK(pidgin_media_delete_event_cb), media);

```

Reviewed at https://reviews.imfreedom.org/r/1565/
--- a/pidgin/gtkmedia.c Mon Aug 01 23:46:24 2022 -0500
+++ b/pidgin/gtkmedia.c Tue Aug 02 00:20:10 2022 -0500
@@ -32,6 +32,7 @@
#include "gtkmedia.h"
#include "gtkutils.h"
#include "pidgincore.h"
+#include "pidginkeypad.h"
#ifdef USE_VV
@@ -653,96 +654,14 @@
}
static void
-phone_dtmf_pressed_cb(GtkButton *button, gpointer user_data)
+pidgin_media_keypad_pressed_cb(PidginKeypad *keypad, guint key, gpointer data)
{
- PidginMedia *gtkmedia = user_data;
- gint num;
+ PidginMedia *gtkmedia = data;
gchar *sid;
- num = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "dtmf-digit"));
- sid = g_object_get_data(G_OBJECT(button), "session-id");
-
- purple_media_send_dtmf(gtkmedia->priv->media, sid, num, 25, 50);
-}
-
-static inline GtkWidget *
-phone_create_button(const gchar *text_hi, const gchar *text_lo)
-{
- GtkWidget *button;
- GtkWidget *label_hi;
- GtkWidget *label_lo;
- GtkWidget *grid;
- const gchar *text_hi_local;
-
- if (text_hi)
- text_hi_local = _(text_hi);
- else
- text_hi_local = "";
-
- grid = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- gtk_box_set_homogeneous(GTK_BOX(grid), TRUE);
-
- button = gtk_button_new();
- label_hi = gtk_label_new(text_hi_local);
- gtk_box_pack_end(GTK_BOX(grid), label_hi, FALSE, TRUE, 0);
- label_lo = gtk_label_new(text_lo);
- gtk_label_set_use_markup(GTK_LABEL(label_lo), TRUE);
- gtk_box_pack_end(GTK_BOX(grid), label_lo, FALSE, TRUE, 0);
- gtk_container_add(GTK_CONTAINER(button), grid);
-
- return button;
-}
+ sid = g_object_get_data(G_OBJECT(gtkmedia), "session-id");
-static struct phone_label {
- gchar *subtext;
- gchar *text;
- gchar chr;
-} phone_labels[] = {
- {"<b>1</b>", NULL, '1'},
- /* Translators note: These are the letters on the keys of a numeric
- keypad; translate according to the tables in §7 of ETSI ES 202 130:
- http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
- */
- /* Letters on the '2' key of a numeric keypad */
- {"<b>2</b>", N_("ABC"), '2'},
- /* Letters on the '3' key of a numeric keypad */
- {"<b>3</b>", N_("DEF"), '3'},
- /* Letters on the '4' key of a numeric keypad */
- {"<b>4</b>", N_("GHI"), '4'},
- /* Letters on the '5' key of a numeric keypad */
- {"<b>5</b>", N_("JKL"), '5'},
- /* Letters on the '6' key of a numeric keypad */
- {"<b>6</b>", N_("MNO"), '6'},
- /* Letters on the '7' key of a numeric keypad */
- {"<b>7</b>", N_("PQRS"), '7'},
- /* Letters on the '8' key of a numeric keypad */
- {"<b>8</b>", N_("TUV"), '8'},
- /* Letters on the '9' key of a numeric keypad */
- {"<b>9</b>", N_("WXYZ"), '9'},
- {"<b>*</b>", NULL, '*'},
- {"<b>0</b>", NULL, '0'},
- {"<b>#</b>", NULL, '#'},
- {NULL, NULL, 0}
-};
-
-static gboolean
-pidgin_media_dtmf_key_press_event_cb(G_GNUC_UNUSED GtkEventControllerKey *controller,
- guint keyval,
- G_GNUC_UNUSED guint keycode,
- G_GNUC_UNUSED GdkModifierType state,
- gpointer user_data)
-{
- PidginMedia *gtkmedia = user_data;
-
- if ((keyval >= GDK_KEY_0 && keyval <= GDK_KEY_9) ||
- keyval == GDK_KEY_asterisk ||
- keyval == GDK_KEY_numbersign) {
- gchar *sid = g_object_get_data(G_OBJECT(gtkmedia), "session-id");
-
- purple_media_send_dtmf(gtkmedia->priv->media, sid, keyval, 25, 50);
- }
-
- return FALSE;
+ purple_media_send_dtmf(gtkmedia->priv->media, sid, key, 25, 50);
}
static GtkWidget *
@@ -750,42 +669,20 @@
PurpleMediaSessionType type, const gchar *_sid)
{
GtkApplicationWindow *win = GTK_APPLICATION_WINDOW(gtkmedia);
- GtkEventController *event_controller = NULL;
- GtkWidget *grid = gtk_grid_new();
- GtkWidget *button;
- gint index = 0;
-
- gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
- gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
+ GtkWidget *keypad = NULL;
- /* Add buttons */
- for (index = 0; phone_labels[index].subtext != NULL; index++) {
- button = phone_create_button(phone_labels[index].text,
- phone_labels[index].subtext);
- g_signal_connect(button, "pressed",
- G_CALLBACK(phone_dtmf_pressed_cb), gtkmedia);
- g_object_set_data(G_OBJECT(button), "dtmf-digit",
- GINT_TO_POINTER(phone_labels[index].chr));
- g_object_set_data_full(G_OBJECT(button), "session-id",
- g_strdup(_sid), g_free);
- gtk_grid_attach(GTK_GRID(grid), button,
- index % 3, index / 3, 1, 1);
- g_object_set(button, "expand", TRUE, "margin", 2, NULL);
- }
-
- event_controller = gtk_event_controller_key_new(GTK_WIDGET(win));
- g_object_set_data_full(G_OBJECT(win), "pidgin-event-controller",
- event_controller, g_object_unref);
-
- g_signal_connect(event_controller, "key-pressed",
- G_CALLBACK(pidgin_media_dtmf_key_press_event_cb), gtkmedia);
+ keypad = pidgin_keypad_new();
+ pidgin_keypad_set_key_capture_widget(PIDGIN_KEYPAD(keypad),
+ GTK_WIDGET(win));
+ g_signal_connect(keypad, "pressed",
+ G_CALLBACK(pidgin_media_keypad_pressed_cb), gtkmedia);
g_object_set_data_full(G_OBJECT(win), "session-id",
g_strdup(_sid), g_free);
- gtk_widget_show_all(grid);
+ gtk_widget_show_all(keypad);
- return grid;
+ return keypad;
}
static void
--- a/pidgin/meson.build Mon Aug 01 23:46:24 2022 -0500
+++ b/pidgin/meson.build Tue Aug 02 00:20:10 2022 -0500
@@ -39,6 +39,7 @@
'pidginiconname.c',
'pidgininfopane.c',
'pidgininvitedialog.c',
+ 'pidginkeypad.c',
'pidginmessage.c',
'pidginmooddialog.c',
'pidginnotificationconnectionerror.c',
@@ -112,6 +113,7 @@
'pidginiconname.h',
'pidgininfopane.h',
'pidgininvitedialog.h',
+ 'pidginkeypad.h',
'pidginmessage.h',
'pidginmooddialog.h',
'pidginnotificationconnectionerror.h',
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginkeypad.c Tue Aug 02 00:20:10 2022 -0500
@@ -0,0 +1,152 @@
+/*
+ * 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 "pidginkeypad.h"
+
+struct _PidginKeypad {
+ GtkGrid parent;
+};
+
+enum {
+ SIG_PRESSED,
+ N_SIGNALS
+};
+static guint signals[N_SIGNALS] = {0, };
+
+/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+static void
+pidgin_keypad_action_activate(G_GNUC_UNUSED GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ PidginKeypad *keypad = PIDGIN_KEYPAD(data);
+ gint32 num = 0;
+
+ if(!g_variant_is_of_type(parameter, G_VARIANT_TYPE_INT32)) {
+ g_critical("PidginKeypad dtmf action parameter is of incorrect type %s",
+ g_variant_get_type_string(parameter));
+ return;
+ }
+
+ num = g_variant_get_int32(parameter);
+
+ g_signal_emit(keypad, signals[SIG_PRESSED], 0, num);
+}
+
+static gboolean
+pidgin_keypad_key_pressed_cb(G_GNUC_UNUSED GtkEventControllerKey *controller,
+ guint keyval,
+ G_GNUC_UNUSED guint keycode,
+ G_GNUC_UNUSED GdkModifierType state,
+ gpointer data)
+{
+ PidginKeypad *keypad = PIDGIN_KEYPAD(data);
+
+ if(GDK_KEY_KP_0 <= keyval && keyval <= GDK_KEY_KP_9) {
+ /* Normalize to the same ASCII numbers. */
+ keyval = (keyval - GDK_KEY_KP_0) + GDK_KEY_0;
+ }
+
+ if((GDK_KEY_0 <= keyval && keyval <= GDK_KEY_9) ||
+ keyval == GDK_KEY_asterisk ||
+ keyval == GDK_KEY_numbersign) {
+
+ g_signal_emit(keypad, signals[SIG_PRESSED], 0, keyval);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+G_DEFINE_TYPE(PidginKeypad, pidgin_keypad, GTK_TYPE_GRID)
+
+static void
+pidgin_keypad_init(PidginKeypad *keypad) {
+ GtkWidget *widget = GTK_WIDGET(keypad);
+ GSimpleActionGroup *action_group = NULL;
+ GActionEntry actions[] = {
+ {
+ .name = "dtmf",
+ .activate = pidgin_keypad_action_activate,
+ .parameter_type = "i",
+ },
+ };
+
+ gtk_widget_init_template(widget);
+
+ action_group = g_simple_action_group_new();
+ g_action_map_add_action_entries(G_ACTION_MAP(action_group),
+ actions, G_N_ELEMENTS(actions), keypad);
+ gtk_widget_insert_action_group(widget, "keypad",
+ G_ACTION_GROUP(action_group));
+}
+
+static void
+pidgin_keypad_class_init(PidginKeypadClass *klass) {
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+ /**
+ * PidginKeypad::pressed:
+ * @keypad: The #PidginKeypad.
+ * @key: The key that was pressed, [const@Gdk.KEY_0] - [const@Gdk.KEY_9],
+ * [const@Gdk.KEY_asterisk], or [const@Gdk.KEY_numbersign].
+ *
+ * Emitted when a key is pressed (by keyboard or from clicking a button).
+ */
+ signals[SIG_PRESSED] = g_signal_new("pressed",
+ G_TYPE_FROM_CLASS(klass),
+ 0, 0, NULL, NULL, NULL, G_TYPE_NONE,
+ 1, G_TYPE_UINT);
+
+ gtk_widget_class_set_template_from_resource(widget_class,
+ "/im/pidgin/Pidgin3/Keypad/keypad.ui");
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GtkWidget *
+pidgin_keypad_new(void) {
+ return g_object_new(PIDGIN_TYPE_KEYPAD, NULL);
+}
+
+void
+pidgin_keypad_set_key_capture_widget(PidginKeypad *keypad, GtkWidget *widget) {
+ GtkEventController *controller = NULL;
+
+ g_return_if_fail(PIDGIN_IS_KEYPAD(keypad));
+ g_return_if_fail(GTK_IS_WIDGET(widget));
+
+ controller = gtk_event_controller_key_new(widget);
+ gtk_event_controller_set_propagation_phase(controller, GTK_PHASE_CAPTURE);
+ g_signal_connect(controller, "key-pressed",
+ G_CALLBACK(pidgin_keypad_key_pressed_cb), keypad);
+ g_object_set_data_full(G_OBJECT(widget), "pidgin-keypad-key-controller",
+ controller, g_object_unref);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginkeypad.h Tue Aug 02 00:20:10 2022 -0500
@@ -0,0 +1,75 @@
+/*
+ * 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_KEYPAD_H
+#define PIDGIN_KEYPAD_H
+
+#include <gtk/gtk.h>
+
+#include <purple.h>
+
+/**
+ * PidginKeypad:
+ *
+ * #PidginKeypad is a widget that displays a DTMF keypad, with the digits 0-9,
+ * an asterisk, and a number sign.
+ *
+ * Since: 3.0.0
+ */
+
+G_BEGIN_DECLS
+
+#define PIDGIN_TYPE_KEYPAD pidgin_keypad_get_type()
+G_DECLARE_FINAL_TYPE(PidginKeypad, pidgin_keypad, PIDGIN, KEYPAD, GtkGrid)
+
+/**
+ * pidgin_keypad_new:
+ *
+ * Creates a new #PidginKeypad.
+ *
+ * Returns: (transfer full): The new instance.
+ *
+ * Since: 3.0.0
+ */
+GtkWidget *pidgin_keypad_new(void);
+
+/**
+ * pidgin_keypad_set_key_capture_widget:
+ * @keypad: The keypad.
+ * @widget: A widget to capture keys from.
+ *
+ * Sets @widget as the widget that @keypad will capture key events from.
+ *
+ * If key events are handled by the keypad, the DTMF digits will be captured
+ * and trigger the pressed signal on @keypad.
+ *
+ * Since: 3.0.0
+ */
+void pidgin_keypad_set_key_capture_widget(PidginKeypad *keypad, GtkWidget *widget);
+
+G_END_DECLS
+
+#endif /* PIDGIN_KEYPAD_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/resources/Keypad/keypad.ui Tue Aug 02 00:20:10 2022 -0500
@@ -0,0 +1,759 @@
+<?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"/>
+ <!-- interface-license-type gplv2 -->
+ <!-- interface-name Pidgin -->
+ <!-- interface-description Internet Messenger -->
+ <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
+ <!-- n-columns=3 n-rows=4 -->
+ <template class="PidginKeypad" parent="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="row-homogeneous">True</property>
+ <property name="column-homogeneous">True</property>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-left">2</property>
+ <property name="margin-right">2</property>
+ <property name="margin-start">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="action-name">keypad.dtmf</property>
+ <property name="action-target">49</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">1</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="secondary_labels[1]">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <style>
+ <class name="image-button"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-left">2</property>
+ <property name="margin-right">2</property>
+ <property name="margin-start">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="action-name">keypad.dtmf</property>
+ <property name="action-target">50</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">2</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="secondary_labels[2]">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <!-- Translators: These are the letters on the '2' key of a numeric
+ keypad; translate according to the tables in §7 of ETSI ES 202 130:
+ http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
+ -->
+ <property name="label" translatable="yes">ABC</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-left">2</property>
+ <property name="margin-right">2</property>
+ <property name="margin-start">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="action-name">keypad.dtmf</property>
+ <property name="action-target">51</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">3</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="secondary_labels[3]">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <!-- Translators: These are the letters on the '3' key of a numeric
+ keypad; translate according to the tables in §7 of ETSI ES 202 130:
+ http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
+ -->
+ <property name="label" translatable="yes">DEF</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-left">2</property>
+ <property name="margin-right">2</property>
+ <property name="margin-start">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="action-name">keypad.dtmf</property>
+ <property name="action-target">52</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">4</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="secondary_labels[4]">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <!-- Translators: These are the letters on the '4' key of a numeric
+ keypad; translate according to the tables in §7 of ETSI ES 202 130:
+ http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
+ -->
+ <property name="label" translatable="yes">GHI</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-left">2</property>
+ <property name="margin-right">2</property>
+ <property name="margin-start">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="action-name">keypad.dtmf</property>
+ <property name="action-target">53</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">5</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="secondary_labels[5]">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <!-- Translators: These are the letters on the '5' key of a numeric
+ keypad; translate according to the tables in §7 of ETSI ES 202 130:
+ http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
+ -->
+ <property name="label" translatable="yes">JKL</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-left">2</property>
+ <property name="margin-right">2</property>
+ <property name="margin-start">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="action-name">keypad.dtmf</property>
+ <property name="action-target">54</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">6</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="secondary_labels[6]">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <!-- Translators: These are the letters on the '6' key of a numeric
+ keypad; translate according to the tables in §7 of ETSI ES 202 130:
+ http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
+ -->
+ <property name="label" translatable="yes">MNO</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-left">2</property>
+ <property name="margin-right">2</property>
+ <property name="margin-start">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="action-name">keypad.dtmf</property>
+ <property name="action-target">55</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">7</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="secondary_labels[7]">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <!-- Translators: These are the letters on the '7' key of a numeric
+ keypad; translate according to the tables in §7 of ETSI ES 202 130:
+ http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
+ -->
+ <property name="label" translatable="yes">PQRS</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-left">2</property>
+ <property name="margin-right">2</property>
+ <property name="margin-start">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="action-name">keypad.dtmf</property>
+ <property name="action-target">56</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">8</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="secondary_labels[8]">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <!-- Translators: These are the letters on the '8' key of a numeric
+ keypad; translate according to the tables in §7 of ETSI ES 202 130:
+ http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
+ -->
+ <property name="label" translatable="yes">TUV</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-left">2</property>
+ <property name="margin-right">2</property>
+ <property name="margin-start">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="action-name">keypad.dtmf</property>
+ <property name="action-target">57</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">9</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="secondary_labels[9]">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <!-- Translators: These are the letters on the '9' key of a numeric
+ keypad; translate according to the tables in §7 of ETSI ES 202 130:
+ http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
+ -->
+ <property name="label" translatable="yes">WXYZ</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-left">2</property>
+ <property name="margin-right">2</property>
+ <property name="margin-start">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="action-name">keypad.dtmf</property>
+ <property name="action-target">42</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">*</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="asterisk">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-left">2</property>
+ <property name="margin-right">2</property>
+ <property name="margin-start">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="action-name">keypad.dtmf</property>
+ <property name="action-target">48</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="secondary_labels[0]">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-left">2</property>
+ <property name="margin-right">2</property>
+ <property name="margin-start">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="action-name">keypad.dtmf</property>
+ <property name="action-target">35</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">#</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="octothorpe">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ </template>
+</interface>
--- a/pidgin/resources/pidgin.gresource.xml Mon Aug 01 23:46:24 2022 -0500
+++ b/pidgin/resources/pidgin.gresource.xml Tue Aug 02 00:20:10 2022 -0500
@@ -18,6 +18,7 @@
<file compressed="true">Debug/debug.ui</file>
<file compressed="true">Debug/filter.css</file>
<file compressed="true">Debug/plugininfo.ui</file>
+ <file compressed="true">Keypad/keypad.ui</file>
<file compressed="true">Log/log-viewer.ui</file>
<file compressed="true">Notifications/connectionerror.ui</file>
<file compressed="true">Notifications/list.ui</file>
--- a/po/POTFILES.in Mon Aug 01 23:46:24 2022 -0500
+++ b/po/POTFILES.in Tue Aug 02 00:20:10 2022 -0500
@@ -356,6 +356,7 @@
pidgin/pidginiconname.c
pidgin/pidgininfopane.c
pidgin/pidgininvitedialog.c
+pidgin/pidginkeypad.c
pidgin/pidginmessage.c
pidgin/pidginmooddialog.c
pidgin/pidginplugininfo.c
@@ -405,6 +406,7 @@
pidgin/resources/Conversations/window.ui
pidgin/resources/Debug/debug.ui
pidgin/resources/Debug/plugininfo.ui
+pidgin/resources/Keypad/keypad.ui
pidgin/resources/Log/log-viewer.ui
pidgin/resources/Plugins/dialog.ui
pidgin/resources/Plugins/menu.ui