[ekiga/ds-gtk-application] GmInfoBar: Add the ability to display several messages.
- From: Damien Sandras <dsandras src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ekiga/ds-gtk-application] GmInfoBar: Add the ability to display several messages.
- Date: Sun, 16 Nov 2014 11:54:48 +0000 (UTC)
commit a04f4a211e16c6032d56d2aebba494e995655bd6
Author: Damien Sandras <dsandras seconix com>
Date: Sun Nov 16 12:46:34 2014 +0100
GmInfoBar: Add the ability to display several messages.
It often happens that the application generates several messages that
the user needs to acknowledge. The previous implementation was able to
display one message at a time, overriding older messages without
allowing the user to acknowledge or read them. This is now fixed by the
implementation of a stack of messages.
lib/engine/gui/gtk-frontend/call-window.cpp | 38 ++++----
lib/engine/gui/gtk-frontend/main_window.cpp | 14 ++--
lib/gui/gm-info-bar.c | 120 ++++++++++++++++++++++++---
lib/gui/gm-info-bar.h | 8 +-
4 files changed, 138 insertions(+), 42 deletions(-)
---
diff --git a/lib/engine/gui/gtk-frontend/call-window.cpp b/lib/engine/gui/gtk-frontend/call-window.cpp
index 11f6cc0..684674b 100644
--- a/lib/engine/gui/gtk-frontend/call-window.cpp
+++ b/lib/engine/gui/gtk-frontend/call-window.cpp
@@ -527,9 +527,9 @@ on_videooutput_device_error_cb (Ekiga::VideoOutputManager & /* manager */,
{
EkigaCallWindow *self = EKIGA_CALL_WINDOW (data);
- gm_info_bar_set_message (GM_INFO_BAR (self->priv->info_bar),
- GTK_MESSAGE_ERROR,
- _("There was an error opening or initializing the video output. Please verify
that no other application is using the accelerated video output."));
+ gm_info_bar_push_message (GM_INFO_BAR (self->priv->info_bar),
+ GTK_MESSAGE_ERROR,
+ _("There was an error opening or initializing the video output. Please verify
that no other application is using the accelerated video output."));
}
@@ -627,9 +627,9 @@ on_videoinput_device_error_cb (Ekiga::VideoInputManager & /* manager */,
break;
}
- gm_info_bar_set_message (GM_INFO_BAR (self->priv->info_bar),
- GTK_MESSAGE_ERROR,
- message);
+ gm_info_bar_push_message (GM_INFO_BAR (self->priv->info_bar),
+ GTK_MESSAGE_ERROR,
+ message);
g_free (message);
}
@@ -683,8 +683,8 @@ on_audioinput_device_error_cb (Ekiga::AudioInputManager & /* manager */,
break;
}
- gm_info_bar_set_message (GM_INFO_BAR (self->priv->info_bar),
- GTK_MESSAGE_ERROR, message);
+ gm_info_bar_push_message (GM_INFO_BAR (self->priv->info_bar),
+ GTK_MESSAGE_ERROR, message);
g_free (message);
}
@@ -751,8 +751,8 @@ on_audiooutput_device_error_cb (Ekiga::AudioOutputManager & /*manager */,
break;
}
- gm_info_bar_set_message (GM_INFO_BAR (self->priv->info_bar),
- GTK_MESSAGE_ERROR, message);
+ gm_info_bar_push_message (GM_INFO_BAR (self->priv->info_bar),
+ GTK_MESSAGE_ERROR, message);
g_free (message);
}
@@ -844,8 +844,8 @@ on_cleared_call_cb (G_GNUC_UNUSED boost::shared_ptr<Ekiga::CallManager> manager,
ekiga_call_window_clear_signal_levels (self);
- gm_info_bar_set_message (GM_INFO_BAR (self->priv->info_bar),
- GTK_MESSAGE_INFO, reason.c_str ());
+ gm_info_bar_push_message (GM_INFO_BAR (self->priv->info_bar),
+ GTK_MESSAGE_INFO, reason.c_str ());
}
static void on_missed_call_cb (boost::shared_ptr<Ekiga::CallManager> /*manager*/,
@@ -870,8 +870,8 @@ on_held_call_cb (boost::shared_ptr<Ekiga::CallManager> /*manager*/,
{
EkigaCallWindow *self = EKIGA_CALL_WINDOW (data);
- gm_info_bar_set_message (GM_INFO_BAR (self->priv->info_bar),
- GTK_MESSAGE_INFO, _("Call on hold"));
+ gm_info_bar_push_message (GM_INFO_BAR (self->priv->info_bar),
+ GTK_MESSAGE_INFO, _("Call on hold"));
}
@@ -882,8 +882,8 @@ on_retrieved_call_cb (boost::shared_ptr<Ekiga::CallManager> /*manager*/,
{
EkigaCallWindow *self = EKIGA_CALL_WINDOW (data);
- gm_info_bar_set_message (GM_INFO_BAR (self->priv->info_bar),
- GTK_MESSAGE_INFO, _("Call retrieved"));
+ gm_info_bar_push_message (GM_INFO_BAR (self->priv->info_bar),
+ GTK_MESSAGE_INFO, _("Call retrieved"));
}
@@ -1218,9 +1218,9 @@ ekiga_call_window_update_stats (EkigaCallWindow *self,
g_free (stats_msg);
if (jitter > 150 || lost > 0.02 || late > 0.02 || out_of_order > 0.02)
- gm_info_bar_set_message (GM_INFO_BAR (self->priv->info_bar),
- GTK_MESSAGE_WARNING,
- _("The call quality is rather bad. Please check your Internet connection."));
+ gm_info_bar_push_message (GM_INFO_BAR (self->priv->info_bar),
+ GTK_MESSAGE_WARNING,
+ _("The call quality is rather bad. Please check your Internet connection."));
}
diff --git a/lib/engine/gui/gtk-frontend/main_window.cpp b/lib/engine/gui/gtk-frontend/main_window.cpp
index 9824e5b..21dcfac 100644
--- a/lib/engine/gui/gtk-frontend/main_window.cpp
+++ b/lib/engine/gui/gtk-frontend/main_window.cpp
@@ -315,9 +315,9 @@ place_call_cb (GtkWidget * /*widget*/,
// Dial
if (!mw->priv->call_core->dial (uri))
- gm_info_bar_set_message (GM_INFO_BAR (mw->priv->info_bar),
- GTK_MESSAGE_ERROR,
- _("Could not connect to remote host"));
+ gm_info_bar_push_message (GM_INFO_BAR (mw->priv->info_bar),
+ GTK_MESSAGE_ERROR,
+ _("Could not connect to remote host"));
}
}
@@ -358,8 +358,8 @@ on_account_updated (Ekiga::BankPtr /*bank*/,
account->get_name ().c_str (),
account->get_status ().c_str ());
- gm_info_bar_set_message (GM_INFO_BAR (self->priv->info_bar),
- GTK_MESSAGE_ERROR, msg);
+ gm_info_bar_push_message (GM_INFO_BAR (self->priv->info_bar),
+ GTK_MESSAGE_ERROR, msg);
g_free (msg);
break;
@@ -468,8 +468,8 @@ static void on_missed_call_cb (boost::shared_ptr<Ekiga::CallManager> /*manager*
gchar* info = NULL;
info = g_strdup_printf (_("Missed call from %s"),
call->get_remote_party_name ().c_str ());
- gm_info_bar_set_message (GM_INFO_BAR (mw->priv->info_bar),
- GTK_MESSAGE_INFO, info);
+ gm_info_bar_push_message (GM_INFO_BAR (mw->priv->info_bar),
+ GTK_MESSAGE_INFO, info);
g_free (info);
// FIXME: the engine should take care of this
diff --git a/lib/gui/gm-info-bar.c b/lib/gui/gm-info-bar.c
index 5583e0f..166f9dc 100644
--- a/lib/gui/gm-info-bar.c
+++ b/lib/gui/gm-info-bar.c
@@ -44,8 +44,16 @@ struct _GmInfoBarPrivate {
GtkWidget *label;
guint timeout;
+ GSList *messages;
};
+typedef struct _GmMessage {
+
+ GtkMessageType type;
+ gchar *message;
+} GmMessage;
+
+
G_DEFINE_TYPE (GmInfoBar, gm_info_bar, GTK_TYPE_INFO_BAR);
@@ -65,15 +73,29 @@ static void gm_info_bar_class_init (GmInfoBarClass *);
static void gm_info_bar_init (GmInfoBar *);
+/* Static helpers */
+static void gm_info_bar_pop_message (GmInfoBar *self);
+
+static gboolean gm_info_bar_display_last_message (GmInfoBar *self);
+
+static void gm_info_bar_display_message (GmInfoBar *self,
+ GtkMessageType type,
+ const char *message);
+
+
/* Callbacks */
static gboolean
on_info_bar_delayed_hide (gpointer self)
{
- gtk_widget_hide (GTK_WIDGET (self));
+ g_return_if_fail (GM_IS_INFO_BAR (self));
+ /* Display (again) the new last element or hide the infobar */
+ if (!gm_info_bar_display_last_message (self))
+ gtk_widget_hide (GTK_WIDGET (self));
return FALSE;
}
+
static void
on_info_bar_response (GmInfoBar *self,
gint response_id,
@@ -81,8 +103,9 @@ on_info_bar_response (GmInfoBar *self,
{
g_return_if_fail (GM_IS_INFO_BAR (self));
- if (response_id == GTK_RESPONSE_CLOSE)
- gtk_widget_hide (GTK_WIDGET (self));
+ if (response_id == GTK_RESPONSE_CLOSE) {
+ gm_info_bar_pop_message (self);
+ }
}
@@ -121,6 +144,7 @@ gm_info_bar_init (GmInfoBar* self)
self->priv->timeout = 0;
self->priv->label = gtk_label_new (NULL);
+ self->priv->messages = NULL;
gtk_label_set_line_wrap (GTK_LABEL (self->priv->label), TRUE);
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (self))),
@@ -131,21 +155,57 @@ gm_info_bar_init (GmInfoBar* self)
}
-/* public api */
-GtkWidget *
-gm_info_bar_new ()
+/* Helpers */
+static void
+gm_info_bar_pop_message (GmInfoBar *self)
{
- return GTK_WIDGET (g_object_new (GM_TYPE_INFO_BAR, NULL));
+ GmInfoBarPrivate *priv = GM_INFO_BAR (self)->priv;
+
+ if (!priv->messages)
+ return;
+
+ /* Display the oldest message */
+ GSList *last = g_slist_last (priv->messages);
+ if (last) {
+ /* Free the last element */
+ GmMessage *m = (GmMessage *) last->data;
+ priv->messages = g_slist_remove_link (priv->messages, last);
+ g_free (m->message);
+ g_slist_free_1 (last);
+
+ /* Display the new last element or hide the infobar */
+ if (!gm_info_bar_display_last_message (self))
+ gtk_widget_hide (GTK_WIDGET (self));
+ }
}
-void
-gm_info_bar_set_message (GmInfoBar *self,
- GtkMessageType type,
- const char *message)
+static gboolean
+gm_info_bar_display_last_message (GmInfoBar *self)
{
- g_return_if_fail (GM_IS_INFO_BAR (self) || !message || !g_strcmp0 (message, ""));
+ GmInfoBarPrivate *priv = GM_INFO_BAR (self)->priv;
+ GSList *last = NULL;
+
+ if (!priv->messages)
+ return FALSE;
+
+ /* Display the new last element or hide the infobar */
+ last = g_slist_last (priv->messages);
+ if (last) {
+ GmMessage *m = (GmMessage *) last->data;
+ gm_info_bar_display_message (self, m->type, m->message);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+gm_info_bar_display_message (GmInfoBar *self,
+ GtkMessageType type,
+ const char *message)
+{
gtk_info_bar_set_message_type (GTK_INFO_BAR (self), type);
gtk_label_set_text (GTK_LABEL (self->priv->label), message);
gtk_info_bar_set_show_close_button (GTK_INFO_BAR (self), (type != GTK_MESSAGE_INFO));
@@ -157,3 +217,39 @@ gm_info_bar_set_message (GmInfoBar *self,
self->priv->timeout = g_timeout_add_seconds (4, on_info_bar_delayed_hide, self);
}
}
+
+
+/* public api */
+GtkWidget *
+gm_info_bar_new ()
+{
+ return GTK_WIDGET (g_object_new (GM_TYPE_INFO_BAR, NULL));
+}
+
+
+void
+gm_info_bar_push_message (GmInfoBar *self,
+ GtkMessageType type,
+ const char *message)
+{
+ GmMessage *m = NULL;
+ gboolean was_empty = FALSE;
+ g_return_if_fail (GM_IS_INFO_BAR (self) || !message || !g_strcmp0 (message, ""));
+
+ was_empty = (g_slist_length (self->priv->messages) == 0);
+
+ if (type == GTK_MESSAGE_INFO) {
+ gm_info_bar_display_message (self, type, message);
+ return;
+ }
+
+ m = g_malloc0 (sizeof (GmMessage));
+ m->type = type;
+ m->message = g_strdup (message);
+
+ /* Last message first */
+ self->priv->messages = g_slist_prepend (self->priv->messages, m);
+
+ if (was_empty)
+ gm_info_bar_display_message (self, type, message);
+}
diff --git a/lib/gui/gm-info-bar.h b/lib/gui/gm-info-bar.h
index b980786..1cf8c4b 100644
--- a/lib/gui/gm-info-bar.h
+++ b/lib/gui/gm-info-bar.h
@@ -63,11 +63,11 @@ GtkWidget *gm_info_bar_new ();
/** Update the GmInfoBar content.
* @param self: A GmInfoBar
* @param type: The message type.
- * @param message: The non empty information message to display.
+ * @param message: The non empty information message to push for display.
*/
-void gm_info_bar_set_message (GmInfoBar *self,
- GtkMessageType type,
- const char *message);
+void gm_info_bar_push_message (GmInfoBar *self,
+ GtkMessageType type,
+ const char *message);
/* GObject thingies */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]