mirror of
https://gitlab.gnome.org/GNOME/calls.git
synced 2024-12-12 15:47:35 +00:00
main-window: Add dialog to handle USSD
This commit is contained in:
parent
949ef90e03
commit
1c89bf292c
2 changed files with 313 additions and 1 deletions
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "calls-main-window.h"
|
#include "calls-main-window.h"
|
||||||
#include "calls-origin.h"
|
#include "calls-origin.h"
|
||||||
|
#include "calls-ussd.h"
|
||||||
#include "calls-call-holder.h"
|
#include "calls-call-holder.h"
|
||||||
#include "calls-call-selector-item.h"
|
#include "calls-call-selector-item.h"
|
||||||
#include "calls-new-call-box.h"
|
#include "calls-new-call-box.h"
|
||||||
|
@ -53,6 +54,16 @@ struct _CallsMainWindow
|
||||||
GtkLabel *permanent_error_label;
|
GtkLabel *permanent_error_label;
|
||||||
|
|
||||||
CallsNewCallBox *new_call;
|
CallsNewCallBox *new_call;
|
||||||
|
|
||||||
|
GtkDialog *ussd_dialog;
|
||||||
|
GtkStack *ussd_stack;
|
||||||
|
GtkSpinner *ussd_spinner;
|
||||||
|
GtkBox *ussd_content;
|
||||||
|
GtkLabel *ussd_label;
|
||||||
|
GtkEntry *ussd_entry;
|
||||||
|
GtkButton *ussd_close_button;
|
||||||
|
GtkButton *ussd_cancel_button;
|
||||||
|
GtkButton *ussd_reply_button;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (CallsMainWindow, calls_main_window, GTK_TYPE_APPLICATION_WINDOW);
|
G_DEFINE_TYPE (CallsMainWindow, calls_main_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||||
|
@ -119,6 +130,158 @@ static const GActionEntry window_entries [] =
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_update_ussd_state (CallsMainWindow *self,
|
||||||
|
CallsUssd *ussd)
|
||||||
|
{
|
||||||
|
CallsUssdState state;
|
||||||
|
|
||||||
|
g_assert (CALLS_IS_MAIN_WINDOW (self));
|
||||||
|
g_assert (CALLS_IS_USSD (ussd));
|
||||||
|
|
||||||
|
state = calls_ussd_get_state (ussd);
|
||||||
|
|
||||||
|
/* If state changed in an active USSD session, don't update */
|
||||||
|
if (state == CALLS_USSD_STATE_ACTIVE &&
|
||||||
|
gtk_widget_get_visible (GTK_WIDGET (self->ussd_reply_button)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
gtk_widget_set_visible (GTK_WIDGET (self->ussd_reply_button),
|
||||||
|
state == CALLS_USSD_STATE_USER_RESPONSE);
|
||||||
|
gtk_widget_set_visible (GTK_WIDGET (self->ussd_entry),
|
||||||
|
state == CALLS_USSD_STATE_USER_RESPONSE);
|
||||||
|
|
||||||
|
if (state == CALLS_USSD_STATE_USER_RESPONSE ||
|
||||||
|
state == CALLS_USSD_STATE_ACTIVE)
|
||||||
|
gtk_widget_show (GTK_WIDGET (self->ussd_cancel_button));
|
||||||
|
else
|
||||||
|
gtk_widget_show (GTK_WIDGET (self->ussd_close_button));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_ussd_added_cb (CallsMainWindow *self,
|
||||||
|
CallsUssd *ussd,
|
||||||
|
char *response)
|
||||||
|
{
|
||||||
|
g_assert (CALLS_IS_MAIN_WINDOW (self));
|
||||||
|
g_assert (CALLS_IS_USSD (ussd));
|
||||||
|
|
||||||
|
if (!response || !*response)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gtk_label_set_label (self->ussd_label, response);
|
||||||
|
g_object_set_data_full (G_OBJECT (self->ussd_dialog), "ussd",
|
||||||
|
g_object_ref (ussd), g_object_unref);
|
||||||
|
window_update_ussd_state (self, ussd);
|
||||||
|
gtk_window_present (GTK_WINDOW (self->ussd_dialog));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_ussd_cancel_clicked_cb (CallsMainWindow *self)
|
||||||
|
{
|
||||||
|
CallsUssd *ussd;
|
||||||
|
|
||||||
|
g_assert (CALLS_IS_MAIN_WINDOW (self));
|
||||||
|
|
||||||
|
ussd = g_object_get_data (G_OBJECT (self->ussd_dialog), "ussd");
|
||||||
|
|
||||||
|
if (ussd)
|
||||||
|
calls_ussd_cancel_async (ussd, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
gtk_window_close (GTK_WINDOW (self->ussd_dialog));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_ussd_entry_changed_cb (CallsMainWindow *self,
|
||||||
|
GtkEntry *entry)
|
||||||
|
{
|
||||||
|
const char *text;
|
||||||
|
gboolean allow_send;
|
||||||
|
|
||||||
|
g_assert (CALLS_IS_MAIN_WINDOW (self));
|
||||||
|
g_assert (GTK_IS_ENTRY (entry));
|
||||||
|
|
||||||
|
text = gtk_entry_get_text (entry);
|
||||||
|
allow_send = text && *text;
|
||||||
|
|
||||||
|
gtk_widget_set_sensitive (GTK_WIDGET (self->ussd_reply_button), allow_send);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_ussd_respond_cb (GObject *object,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
CallsMainWindow *self = user_data;
|
||||||
|
g_autofree char *response = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
CallsUssd *ussd;
|
||||||
|
|
||||||
|
ussd = g_object_get_data (G_OBJECT (self->ussd_dialog), "ussd");
|
||||||
|
response = calls_ussd_respond_finish (ussd, result, &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
gtk_dialog_response (self->ussd_dialog, GTK_RESPONSE_CLOSE);
|
||||||
|
g_warning ("USSD Error: %s", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response && *response)
|
||||||
|
{
|
||||||
|
window_update_ussd_state (self, ussd);
|
||||||
|
gtk_label_set_text (self->ussd_label, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_spinner_stop (self->ussd_spinner);
|
||||||
|
gtk_stack_set_visible_child (self->ussd_stack, GTK_WIDGET (self->ussd_content));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_ussd_reply_clicked_cb (CallsMainWindow *self)
|
||||||
|
{
|
||||||
|
CallsUssd *ussd;
|
||||||
|
g_autofree char *response = NULL;
|
||||||
|
|
||||||
|
g_assert (CALLS_IS_MAIN_WINDOW (self));
|
||||||
|
|
||||||
|
ussd = g_object_get_data (G_OBJECT (self->ussd_dialog), "ussd");
|
||||||
|
g_assert (CALLS_IS_USSD (ussd));
|
||||||
|
|
||||||
|
response = g_strdup (gtk_entry_get_text (self->ussd_entry));
|
||||||
|
gtk_entry_set_text (self->ussd_entry, "");
|
||||||
|
calls_ussd_respond_async (ussd, response, NULL,
|
||||||
|
window_ussd_respond_cb, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
main_window_ussd_send_cb (GObject *object,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
CallsMainWindow *self = user_data;
|
||||||
|
g_autofree char *response = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
CallsUssd *ussd;
|
||||||
|
|
||||||
|
response = calls_new_call_box_send_ussd_finish (self->new_call, result, &error);
|
||||||
|
ussd = g_task_get_task_data (G_TASK (result));
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
gtk_dialog_response (self->ussd_dialog, GTK_RESPONSE_CLOSE);
|
||||||
|
g_warning ("USSD Error: %s", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_set_data_full (G_OBJECT (self->ussd_dialog), "ussd",
|
||||||
|
g_object_ref (ussd), g_object_unref);
|
||||||
|
window_update_ussd_state (self, ussd);
|
||||||
|
gtk_label_set_text (self->ussd_label, response);
|
||||||
|
gtk_spinner_stop (self->ussd_spinner);
|
||||||
|
gtk_stack_set_visible_child (self->ussd_stack, GTK_WIDGET (self->ussd_content));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_property (GObject *object,
|
set_property (GObject *object,
|
||||||
guint property_id,
|
guint property_id,
|
||||||
|
@ -185,6 +348,16 @@ constructed (GObject *object)
|
||||||
G_CALLBACK (calls_in_app_notification_show),
|
G_CALLBACK (calls_in_app_notification_show),
|
||||||
self->in_app_notification);
|
self->in_app_notification);
|
||||||
|
|
||||||
|
g_signal_connect_swapped (calls_manager_get_default (),
|
||||||
|
"ussd-added",
|
||||||
|
G_CALLBACK (window_ussd_added_cb),
|
||||||
|
self);
|
||||||
|
g_signal_connect_swapped (calls_manager_get_default (),
|
||||||
|
"ussd-state-changed",
|
||||||
|
G_CALLBACK (window_update_ussd_state),
|
||||||
|
self);
|
||||||
|
gtk_window_set_transient_for (GTK_WINDOW (self->ussd_dialog), GTK_WINDOW (self));
|
||||||
|
|
||||||
// Add new call box
|
// Add new call box
|
||||||
self->new_call = calls_new_call_box_new ();
|
self->new_call = calls_new_call_box_new ();
|
||||||
widget = GTK_WIDGET (self->new_call);
|
widget = GTK_WIDGET (self->new_call);
|
||||||
|
@ -283,6 +456,20 @@ calls_main_window_class_init (CallsMainWindowClass *klass)
|
||||||
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, main_stack);
|
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, main_stack);
|
||||||
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, permanent_error_revealer);
|
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, permanent_error_revealer);
|
||||||
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, permanent_error_label);
|
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, permanent_error_label);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, ussd_dialog);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, ussd_stack);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, ussd_spinner);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, ussd_content);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, ussd_label);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, ussd_entry);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, ussd_close_button);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, ussd_cancel_button);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, ussd_reply_button);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, window_ussd_cancel_clicked_cb);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, window_ussd_entry_changed_cb);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, window_ussd_reply_clicked_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,6 +497,21 @@ calls_main_window_new (GtkApplication *application,
|
||||||
void
|
void
|
||||||
calls_main_window_dial (CallsMainWindow *self,
|
calls_main_window_dial (CallsMainWindow *self,
|
||||||
const gchar *target)
|
const gchar *target)
|
||||||
|
{
|
||||||
|
if (calls_number_is_ussd (target))
|
||||||
|
{
|
||||||
|
gtk_widget_hide (GTK_WIDGET (self->ussd_cancel_button));
|
||||||
|
gtk_widget_hide (GTK_WIDGET (self->ussd_reply_button));
|
||||||
|
gtk_stack_set_visible_child (self->ussd_stack, GTK_WIDGET (self->ussd_spinner));
|
||||||
|
gtk_spinner_start (self->ussd_spinner);
|
||||||
|
|
||||||
|
calls_new_call_box_send_ussd_async (self->new_call, target, NULL,
|
||||||
|
main_window_ussd_send_cb, self);
|
||||||
|
|
||||||
|
gtk_window_present (GTK_WINDOW (self->ussd_dialog));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
calls_new_call_box_dial (self->new_call, target);
|
calls_new_call_box_dial (self->new_call, target);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -91,4 +91,114 @@
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<object class="GtkDialog" id="ussd_dialog">
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="modal">True</property>
|
||||||
|
<property name="default-width">240</property>
|
||||||
|
<property name="default-height">200</property>
|
||||||
|
<signal name="delete-event" handler="gtk_widget_hide_on_delete" object="ussd_dialog" swapped="yes"/>
|
||||||
|
<child type="titlebar">
|
||||||
|
<object class="GtkHeaderBar">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="show-close-button">False</property>
|
||||||
|
<property name="title" translatable="yes">USSD</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="ussd_cancel_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">True</property>
|
||||||
|
<property name="has-default">True</property>
|
||||||
|
<property name="can-default">True</property>
|
||||||
|
<property name="use-underline">True</property>
|
||||||
|
<property name="label" translatable="yes">_Cancel</property>
|
||||||
|
<signal name="clicked" handler="window_ussd_cancel_clicked_cb" swapped="yes"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="pack_type">start</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="ussd_close_button">
|
||||||
|
<property name="visible" bind-source="ussd_cancel_button" bind-property="visible"
|
||||||
|
bind-flags="sync-create|invert-boolean|bidirectional"/>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">True</property>
|
||||||
|
<property name="has-default">True</property>
|
||||||
|
<property name="can-default">True</property>
|
||||||
|
<property name="use-underline">True</property>
|
||||||
|
<property name="label" translatable="yes">_Close</property>
|
||||||
|
<signal name="clicked" handler="gtk_window_close" object="ussd_dialog" swapped="yes"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="pack_type">start</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="ussd_reply_button">
|
||||||
|
<property name="label" translatable="yes">_Send</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
<property name="use-underline">True</property>
|
||||||
|
<signal name="clicked" handler="window_ussd_reply_clicked_cb" swapped="yes"/>
|
||||||
|
<style>
|
||||||
|
<class name="suggested-action"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="pack-type">end</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="border-width">0</property>
|
||||||
|
<property name="margin">12</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkStack" id="ussd_stack">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox" id="ussd_content">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">12</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="ussd_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="wrap">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="ussd_entry">
|
||||||
|
<property name="visible">False</property>
|
||||||
|
<signal name="changed" handler="window_ussd_entry_changed_cb" swapped="yes"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinner" id="ussd_spinner">
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
|
||||||
</interface>
|
</interface>
|
||||||
|
|
Loading…
Reference in a new issue