gtk_statusbar_push_markup()



I figured that #90286 - "Addition of function gtk_statusbar_push_with_markup()"
would be a quick fix.

Turned out to be a little more complex than this because GtkStatusBar
has two signals:

  void	(*text_pushed)	(GtkStatusbar	*statusbar,
			 guint		 context_id,
			 const gchar	*text);
  void	(*text_popped)	(GtkStatusbar	*statusbar,
			 guint		 context_id,
			 const gchar	*text);

That are called when stuff is pushed or popped, and currently
the text in the statusbar is updated out of the default handler
based on the ::text property.

So, theoretically, someone could override text_pushed/text_popped,
and then chain up with a different value for *text.

But, I really couldn't imagine any valid reason for this (well,
actually, I can't imagine any reason for having these signals
in the first place), so what I did was changed the signals
to be pure notification and have an empty default handler,
then made the code do:

  gtk_statusbar_update (statusbar);
  gtk_signal_emit (GTK_OBJECT (statusbar),
		   statusbar_signals[SIGNAL_TEXT_PUSHED],
		   msg->context_id,
		   msg->text);

Where msg->text is the text of the statusbar with any markup 
stripped out. If someone was setting statusbar->label
in their signal handler, it will still work, because the
update that the widget does is done first.

Patch attached.

Opinions? Anybody ever use these signals? Anybody have any
idea why they are there?

Thanks,
                                        Owen

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.3660
diff -u -p -r1.3660 ChangeLog
--- ChangeLog	25 Sep 2002 15:07:24 -0000	1.3660
+++ ChangeLog	25 Sep 2002 18:38:00 -0000
@@ -1,3 +1,9 @@
+Wed Sep 25 14:32:28 2002  Owen Taylor  <otaylor redhat com>
+
+	* gtk/gtkstatusbar.[ch]: Add gtk_statusbar_push_markup()
+	that pushes a message with GMarkup. Change the ::text_pushed
+	::text_popped signals to be purely informative.
+
 Wed Sep 25 10:51:24 2002  Owen Taylor  <otaylor redhat com>
 
 	* gdk/gdkscreen.h gdk/{x11,win32,linux-fb}/gdkscreen-*.c:
Index: gtk/gtkstatusbar.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkstatusbar.c,v
retrieving revision 1.31
diff -u -p -r1.31 gtkstatusbar.c
--- gtk/gtkstatusbar.c	17 Nov 2001 23:28:51 -0000	1.31
+++ gtk/gtkstatusbar.c	25 Sep 2002 18:38:00 -0000
@@ -37,9 +37,11 @@ typedef struct _GtkStatusbarMsg GtkStatu
 
 struct _GtkStatusbarMsg
 {
-  gchar *text;
+  gchar *label;			/* Including markup */
+  gchar *text;			/* Without markup */
   guint context_id;
   guint message_id;
+  gboolean use_markup;
 };
 
 enum
@@ -52,7 +54,8 @@ enum
 static void     gtk_statusbar_class_init     (GtkStatusbarClass *class);
 static void     gtk_statusbar_init           (GtkStatusbar      *statusbar);
 static void     gtk_statusbar_destroy        (GtkObject         *object);
-static void     gtk_statusbar_update         (GtkStatusbar      *statusbar,
+static void     gtk_statusbar_update         (GtkStatusbar      *statusbar);
+static void     gtk_statusbar_null_handler   (GtkStatusbar      *statusbar,
 					      guint              context_id,
 					      const gchar       *text);
 static void     gtk_statusbar_size_allocate  (GtkWidget         *widget,
@@ -131,8 +134,8 @@ gtk_statusbar_class_init (GtkStatusbarCl
 					       sizeof (GtkStatusbarMsg) * 64,
 					       G_ALLOC_AND_FREE);
 
-  class->text_pushed = gtk_statusbar_update;
-  class->text_popped = gtk_statusbar_update;
+  class->text_pushed = gtk_statusbar_null_handler;
+  class->text_popped = gtk_statusbar_null_handler;
   
   statusbar_signals[SIGNAL_TEXT_PUSHED] =
     gtk_signal_new ("text_pushed",
@@ -204,16 +207,26 @@ gtk_statusbar_new (void)
 }
 
 static void
-gtk_statusbar_update (GtkStatusbar *statusbar,
-		      guint	    context_id,
-		      const gchar  *text)
+gtk_statusbar_update (GtkStatusbar *statusbar)
 {
-  g_return_if_fail (GTK_IS_STATUSBAR (statusbar));
+  GtkStatusbarMsg *msg;
+  
+  msg = statusbar->messages ? statusbar->messages->data : NULL;
 
-  if (!text)
-    text = "";
+  gtk_label_set_label (GTK_LABEL (statusbar->label),
+		       msg ? msg->label : "");
+  gtk_label_set_use_markup (GTK_LABEL (statusbar->label),
+			    msg ? msg->use_markup : FALSE);
+}
 
-  gtk_label_set_text (GTK_LABEL (statusbar->label), text);
+/* This is here in case someone is chaining up without
+ * checking for NULL, since we used to update the text here.
+ */
+static void
+gtk_statusbar_null_handler (GtkStatusbar *statusbar,
+			    guint	    context_id,
+			    const gchar  *text)
+{
 }
 
 guint
@@ -244,32 +257,112 @@ gtk_statusbar_get_context_id (GtkStatusb
 }
 
 guint
-gtk_statusbar_push (GtkStatusbar *statusbar,
-		    guint	  context_id,
-		    const gchar  *text)
+gtk_statusbar_push_internal (GtkStatusbar *statusbar,
+			     guint	   context_id,
+			     const gchar  *text,
+			     gboolean      use_markup)
 {
+  char *text_no_markup;
   GtkStatusbarMsg *msg;
   GtkStatusbarClass *class;
-
-  g_return_val_if_fail (GTK_IS_STATUSBAR (statusbar), 0);
-  g_return_val_if_fail (text != NULL, 0);
+  GError *error = NULL;
 
   class = GTK_STATUSBAR_GET_CLASS (statusbar);
   msg = g_chunk_new (GtkStatusbarMsg, class->messages_mem_chunk);
-  msg->text = g_strdup (text);
+
+  if (use_markup)
+    {
+      if (!pango_parse_markup (text, -1, 0, NULL, &text_no_markup, NULL, &error))
+	{
+	  g_warning ("gtk_statusbar_push_with_markup(): Couldn't parse markup: %s\n",
+		     error->message);
+	  g_error_free (error);
+	  
+	  text = "";
+	  use_markup = FALSE;
+	}
+    }
+  if (!use_markup)
+    {
+      text_no_markup = g_strdup (text);
+    }
+  
+  msg->label = g_strdup (text);
+  msg->text = text_no_markup;
   msg->context_id = context_id;
   msg->message_id = statusbar->seq_message_id++;
+  msg->use_markup = use_markup;
 
   statusbar->messages = g_slist_prepend (statusbar->messages, msg);
 
+  gtk_statusbar_update (statusbar);
   gtk_signal_emit (GTK_OBJECT (statusbar),
 		   statusbar_signals[SIGNAL_TEXT_PUSHED],
 		   msg->context_id,
 		   msg->text);
-
+  
   return msg->message_id;
 }
 
+/**
+ * gtk_statusbar_push:
+ * @statusbar: a #GtkStatusbar.
+ * @context_id: the message's context id, as returned by
+                gtk_statusbar_get_context_id().
+ * @text: the message to add to the statusbar.
+ * 
+ * Pushes a new message onto a statusbar's stack.
+ * 
+ * Return value: the message's new message id for use with gtk_statusbar_remove().
+ **/
+guint
+gtk_statusbar_push (GtkStatusbar *statusbar,
+		    guint	  context_id,
+		    const gchar  *text)
+{
+  g_return_val_if_fail (GTK_IS_STATUSBAR (statusbar), 0);
+  g_return_val_if_fail (text != NULL, 0);
+
+  return gtk_statusbar_push_internal (statusbar, context_id, text, FALSE);
+}
+
+/**
+ * gtk_statusbar_push_with_markup:
+ * @statusbar: a #GtkStatusbar.
+ * @context_id: the message's context id, as returned by
+                gtk_statusbar_get_context_id().
+ * @text: the message to add to the statusbar.
+ * 
+ * Pushes a new message onto a statusbar's stack, using
+ * the <link linkend="PangoMarkupFormat">Pango text markup
+ * language</link>.
+ * 
+ * Return value: the message's new message id for use with gtk_statusbar_remove().
+ **/
+guint
+gtk_statusbar_push_markup (GtkStatusbar *statusbar,
+			   guint	      context_id,
+			   const gchar  *text)
+{
+  g_return_val_if_fail (GTK_IS_STATUSBAR (statusbar), 0);
+  g_return_val_if_fail (text != NULL, 0);
+
+  return gtk_statusbar_push_internal (statusbar, context_id, text, TRUE);
+}
+
+static void
+gtk_statusbar_message_free (GtkStatusbar    *statusbar,
+			    GtkStatusbarMsg *msg)
+{
+  GtkStatusbarClass *class;
+
+  class = GTK_STATUSBAR_GET_CLASS (statusbar);  
+  
+  g_free (msg->text);
+  g_free (msg->label);
+  g_mem_chunk_free (class->messages_mem_chunk, msg);
+}
+
 void
 gtk_statusbar_pop (GtkStatusbar *statusbar,
 		   guint	 context_id)
@@ -294,8 +387,7 @@ gtk_statusbar_pop (GtkStatusbar *statusb
 
 	      statusbar->messages = g_slist_remove_link (statusbar->messages,
 							 list);
-	      g_free (msg->text);
-	      g_mem_chunk_free (class->messages_mem_chunk, msg);
+	      gtk_statusbar_message_free (statusbar, msg);
 	      g_slist_free_1 (list);
 	      break;
 	    }
@@ -304,6 +396,7 @@ gtk_statusbar_pop (GtkStatusbar *statusb
 
   msg = statusbar->messages ? statusbar->messages->data : NULL;
 
+  gtk_statusbar_update (statusbar);
   gtk_signal_emit (GTK_OBJECT (statusbar),
 		   statusbar_signals[SIGNAL_TEXT_POPPED],
 		   (guint) (msg ? msg->context_id : 0),
@@ -344,8 +437,7 @@ gtk_statusbar_remove (GtkStatusbar *stat
 	      
 	      class = GTK_STATUSBAR_GET_CLASS (statusbar);
 	      statusbar->messages = g_slist_remove_link (statusbar->messages, list);
-	      g_free (msg->text);
-	      g_mem_chunk_free (class->messages_mem_chunk, msg);
+	      gtk_statusbar_message_free (statusbar, msg);
 	      g_slist_free_1 (list);
 	      
 	      break;
@@ -402,8 +494,7 @@ gtk_statusbar_destroy (GtkObject *object
       GtkStatusbarMsg *msg;
 
       msg = list->data;
-      g_free (msg->text);
-      g_mem_chunk_free (class->messages_mem_chunk, msg);
+      gtk_statusbar_message_free (statusbar, msg);
     }
   g_slist_free (statusbar->messages);
   statusbar->messages = NULL;
Index: gtk/gtkstatusbar.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkstatusbar.h,v
retrieving revision 1.15
diff -u -p -r1.15 gtkstatusbar.h
--- gtk/gtkstatusbar.h	23 Feb 2002 20:22:04 -0000	1.15
+++ gtk/gtkstatusbar.h	25 Sep 2002 18:38:00 -0000
@@ -92,10 +92,15 @@ GtkWidget* gtk_statusbar_new          	(
  */
 guint	   gtk_statusbar_get_context_id	(GtkStatusbar *statusbar,
 					 const gchar  *context_description);
+
 /* Returns message_id used for gtk_statusbar_remove */
-guint      gtk_statusbar_push          	(GtkStatusbar *statusbar,
-					 guint	       context_id,
+guint      gtk_statusbar_push           (GtkStatusbar *statusbar,
+					 guint         context_id,
 					 const gchar  *text);
+guint      gtk_statusbar_push_markup    (GtkStatusbar *statusbar,
+					 guint         context_id,
+					 const gchar  *text);
+
 void       gtk_statusbar_pop          	(GtkStatusbar *statusbar,
 					 guint	       context_id);
 void       gtk_statusbar_remove        	(GtkStatusbar *statusbar,
Index: tests/testgtk.c
===================================================================
RCS file: /cvs/gnome/gtk+/tests/testgtk.c,v
retrieving revision 1.310
diff -u -p -r1.310 testgtk.c
--- tests/testgtk.c	30 Jul 2002 20:43:15 -0000	1.310
+++ tests/testgtk.c	25 Sep 2002 18:38:01 -0000
@@ -1161,6 +1161,17 @@ statusbar_push (GtkWidget *button,
 }
 
 static void
+statusbar_push_markup (GtkWidget *button,
+		       GtkStatusbar *statusbar)
+{
+  gchar text[1024];
+
+  sprintf (text, "something <span color=\"red\" style=\"italic\">%d</span>", statusbar_counter++);
+
+  gtk_statusbar_push_markup (statusbar, 1, text);
+}
+
+static void
 statusbar_pop (GtkWidget *button,
 	       GtkStatusbar *statusbar)
 {
@@ -1258,6 +1269,15 @@ create_statusbar (GtkWidget *widget)
 			       NULL);
       g_object_connect (G_OBJECT (button),
 			"signal::clicked", statusbar_push, statusbar,
+			NULL);
+
+      button = gtk_widget_new (gtk_button_get_type (),
+			       "label", "push markup",
+			       "visible", TRUE,
+			       "parent", box2,
+			       NULL);
+      g_object_connect (G_OBJECT (button),
+			"signal::clicked", statusbar_push_markup, statusbar,
 			NULL);
 
       button = g_object_connect (gtk_widget_new (gtk_button_get_type (),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]