diff --git a/plugins/sip/calls-sip-account-widget.c b/plugins/sip/calls-sip-account-widget.c
index 032c087..5d44ffe 100644
--- a/plugins/sip/calls-sip-account-widget.c
+++ b/plugins/sip/calls-sip-account-widget.c
@@ -64,6 +64,7 @@ struct _CallsSipAccountWidget {
GtkEntry *user;
GtkEntry *password;
GtkEntry *port;
+ char *last_port;
HdyComboRow *protocol;
GListStore *protocols_store; /* bound model for protocol HdyComboRow */
@@ -74,6 +75,7 @@ struct _CallsSipAccountWidget {
/* misc */
gboolean connecting;
+ gboolean port_self_change;
};
G_DEFINE_TYPE (CallsSipAccountWidget, calls_sip_account_widget, GTK_TYPE_BOX)
@@ -116,6 +118,83 @@ on_text_changed (CallsSipAccountWidget *self)
}
+/*
+ * Stop "insert-text" signal emission if any undesired port
+ * value occurs
+ */
+static void
+on_port_entry_insert_text (CallsSipAccountWidget *self,
+ char *new_text,
+ int new_text_length,
+ gpointer position,
+ GtkEntry *entry)
+{
+ size_t digit_end, len;
+ int *pos;
+
+ g_assert (CALLS_IS_SIP_ACCOUNT_WIDGET (self));
+ g_assert (GTK_IS_ENTRY (entry));
+
+ if (!new_text || !*new_text || self->port_self_change)
+ return;
+
+ pos = (int *)position;
+ g_object_set_data (G_OBJECT (entry), "old-pos", GINT_TO_POINTER (*pos));
+
+ if (new_text_length == -1)
+ len = strlen (new_text);
+ else
+ len = new_text_length;
+
+ digit_end = strspn (new_text, "1234567890");
+
+ /* If user inserted something other than a digit,
+ * stop inserting the text and warn the user.
+ */
+ if (digit_end != len) {
+ g_signal_stop_emission_by_name (entry, "insert-text");
+ gtk_widget_error_bell (GTK_WIDGET (entry));
+ } else {
+ g_free (self->last_port);
+ self->last_port = g_strdup (gtk_entry_get_text (entry));
+ }
+}
+
+
+static gboolean
+update_port_cursor_position (GtkEntry *entry)
+{
+ int pos;
+
+ pos = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (entry), "old-pos"));
+ gtk_editable_set_position (GTK_EDITABLE (entry), pos);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+on_port_entry_after_insert_text (CallsSipAccountWidget *self,
+ char *new_text,
+ int new_text_length,
+ gpointer position,
+ GtkEntry *entry)
+{
+ const char *text;
+ int port = 0;
+
+ text = gtk_entry_get_text (entry);
+ port = (int)g_ascii_strtod (text, NULL);
+
+ /* Reset to the old value if new port number is invalid */
+ if ((port < 0 || port > 65535) && self->last_port) {
+ self->port_self_change = TRUE;
+ gtk_entry_set_text (entry, self->last_port);
+ g_idle_add (G_SOURCE_FUNC (update_port_cursor_position), entry);
+ gtk_widget_error_bell (GTK_WIDGET (entry));
+ self->port_self_change = FALSE;
+ }
+}
+
static void
update_header (CallsSipAccountWidget *self)
{
@@ -348,6 +427,7 @@ calls_sip_account_widget_dispose (GObject *object)
{
CallsSipAccountWidget *self = CALLS_SIP_ACCOUNT_WIDGET (object);
+ g_clear_pointer (&self->last_port, g_free);
g_clear_object (&self->protocols_store);
G_OBJECT_CLASS (calls_sip_account_widget_parent_class)->dispose (object);
@@ -400,6 +480,8 @@ calls_sip_account_widget_class_init (CallsSipAccountWidgetClass *klass)
gtk_widget_class_bind_template_callback (widget_class, on_delete_clicked);
gtk_widget_class_bind_template_callback (widget_class, on_apply_clicked);
gtk_widget_class_bind_template_callback (widget_class, on_text_changed);
+ gtk_widget_class_bind_template_callback (widget_class, on_port_entry_insert_text);
+ gtk_widget_class_bind_template_callback (widget_class, on_port_entry_after_insert_text);
}
diff --git a/plugins/sip/sip-account-widget.ui b/plugins/sip/sip-account-widget.ui
index f4b0478..2363382 100644
--- a/plugins/sip/sip-account-widget.ui
+++ b/plugins/sip/sip-account-widget.ui
@@ -165,6 +165,8 @@
center
digits
+
+