--- gtk+-2.6.4/gtk/gtkhbbox.c	2004-08-09 19:59:52.000000000 +0300
+++ gtk+-2.6.4/gtk/gtkhbbox.c	2005-04-06 16:19:36.644967480 +0300
@@ -24,10 +24,20 @@
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+/* Modified for Nokia Oyj during 2002-2005. See CHANGES file for list
+ * of changes.
+ */
+
+/* Hildon : Button spacing according to the spec. */
+#define HILDON_BUTTON_SPACING 5
+/* Selecting hetefogenous mode for a childlayout */
+#define GTK_BUTTONBOX_HETEROGENOUS 6
+
 #include <config.h>
 #include "gtkalias.h"
 #include "gtkhbbox.h"
-
+/* Hildon : We need this to mess with buttons graphics. */
+#include "gtkbutton.h"
 
 static void gtk_hbutton_box_class_init    (GtkHButtonBoxClass   *klass);
 static void gtk_hbutton_box_init          (GtkHButtonBox        *box);
@@ -36,6 +46,15 @@
 static void gtk_hbutton_box_size_allocate (GtkWidget      *widget,
 					   GtkAllocation  *allocation);
 
+static void osso_gtk_hbutton_child_showhide_handler (GtkWidget *widget,
+						     gpointer user_data);
+static void osso_gtk_hbutton_box_remove_child_signal_handlers (GtkHButtonBox *hbbox,
+							       GtkWidget *removed_widget,
+							       gpointer data);
+static void osso_gtk_hbutton_box_find_button_detail (GtkHButtonBox *hbbox,
+					      GtkWidget *addremovewidget,
+					      gpointer data);
+
 static gint default_spacing = 30;
 static gint default_layout_style = GTK_BUTTONBOX_EDGE;
 
@@ -76,12 +95,23 @@
 
   widget_class->size_request = gtk_hbutton_box_size_request;
   widget_class->size_allocate = gtk_hbutton_box_size_allocate;
+
+  /* HILDON:
+   * Name buttons only if hildon like style property is set
+   */
+  gtk_widget_class_install_style_property (widget_class,
+					   g_param_spec_boolean 
+					   ( "hildonlike",
+					     "hildonlike looks",
+					     "Name buttons, 1/0",
+					     FALSE,
+					     G_PARAM_READABLE) );
 }
 
 static void
 gtk_hbutton_box_init (GtkHButtonBox *hbutton_box)
 {
-	/* button_box_init has done everything allready */
+  /* button_box_init has done everything allready */
 }
 
 GtkWidget*
@@ -91,6 +121,24 @@
 
   hbutton_box = g_object_new (GTK_TYPE_HBUTTON_BOX, NULL);
 
+  /* Attach signal handler for 'hildonizing' buttons.
+   * gtk_hbutton_box_hildonize_buttons will check the name
+   * and if it is something we're interested in i.e.
+   *
+   *   hildon_dialogbuttons
+   *   hildon_viewbuttons
+   *
+   * it will do the hildonizing
+   */
+  g_signal_connect_after (G_OBJECT (hbutton_box), "remove",
+		    G_CALLBACK (osso_gtk_hbutton_box_remove_child_signal_handlers),
+		    NULL);
+  g_signal_connect_after( G_OBJECT( hbutton_box ), "add",
+		  G_CALLBACK( osso_gtk_hbutton_box_find_button_detail ),
+		  NULL );
+  g_signal_connect_after( G_OBJECT( hbutton_box ), "remove",
+		  G_CALLBACK( osso_gtk_hbutton_box_find_button_detail ),
+		  NULL );
   return GTK_WIDGET (hbutton_box);
 }
 
@@ -145,6 +193,11 @@
   gint child_height;
   gint spacing;
   GtkButtonBoxStyle layout;
+  gint child_xpad=0;
+  GtkBoxChild *child_req;
+  GList *children_req;
+  GtkRequisition treq;
+
   
   box = GTK_BOX (widget);
   bbox = GTK_BUTTON_BOX (widget);
@@ -159,6 +212,12 @@
                                      &child_width,
                                      &child_height);
 
+  /* should GTK_BUTTONBOX_HETEROGENOUS add into the GtkButtonBoxStyle 
+     enum struct 
+  */ 
+   if( !box->homogeneous )
+     layout = GTK_BUTTONBOX_HETEROGENOUS; 
+
   if (nvis_children == 0)
   {
     requisition->width = 0; 
@@ -177,11 +236,36 @@
     case GTK_BUTTONBOX_END:
       requisition->width = nvis_children*child_width + ((nvis_children-1)*spacing);
       break;
+    case GTK_BUTTONBOX_HETEROGENOUS:
+      children_req = GTK_BOX (box)->children;
+      child_req = children_req->data;
+      requisition->width = 0; 
+
+      while (children_req)
+	{ 
+	  child_req = children_req->data;
+	  children_req = children_req->next;
+
+	  if (GTK_WIDGET_VISIBLE (child_req->widget))
+	    {
+	      gtk_widget_get_child_requisition( child_req->widget, 
+						&(treq) );   	      
+	      requisition->width += treq.width;
+	 
+              gtk_widget_style_get(widget, 
+				   "child-internal-pad-x", 
+				   &(child_xpad), NULL);
+	      requisition->width  += (child_xpad*2);	      
+	    }
+      	}
+      requisition->width += ((nvis_children-1)*spacing);
+
+      break; 
     default:
       g_assert_not_reached();
       break;
     }
-	  
+    
     requisition->height = child_height;
   }
 	  
@@ -227,6 +311,10 @@
                                      &child_height);
   widget->allocation = *allocation;
   width = allocation->width - GTK_CONTAINER (box)->border_width*2;
+
+  if( !base_box->homogeneous )
+     layout = GTK_BUTTONBOX_HETEROGENOUS;
+
   switch (layout)
   {
   case GTK_BUTTONBOX_SPREAD:
@@ -264,6 +352,39 @@
       - GTK_CONTAINER (box)->border_width;
     secondary_x = allocation->x + GTK_CONTAINER (box)->border_width;
     break;
+  case GTK_BUTTONBOX_HETEROGENOUS:
+    {
+      gint sumwidth = 0;
+      GtkBoxChild *child_h;
+      GList *children_h = GTK_BOX (box)->children;
+        /* heterogenous sized childs onto center */
+      childspacing = spacing;
+      child_h = children_h->data;
+
+      while (children_h )
+	{
+	  if ( g_list_length (children_h) == 0 ) break;  
+
+	  child_h = children_h->data;
+	  children_h = children_h->next;
+
+	  if (GTK_WIDGET_VISIBLE (child_h->widget))
+	    {
+	      gint child_xpad = 0;
+	      GtkRequisition treq;
+	      gtk_widget_get_child_requisition( child_h->widget, &(treq) );  
+	      sumwidth += treq.width;
+
+	      gtk_widget_style_get(widget, 
+				   "child-internal-pad-x", 
+				   &(child_xpad), NULL); 
+	      sumwidth += (child_xpad*2);
+	    }
+	}
+      x = secondary_x = allocation->x + 
+       ( (allocation->width - sumwidth - (spacing * (nvis_children - 1)))/2 );
+      break; 
+    }
   default:
     g_assert_not_reached();
     break;
@@ -282,10 +403,33 @@
 
       if (GTK_WIDGET_VISIBLE (child->widget))
 	{
-	  child_allocation.width = child_width;
 	  child_allocation.height = child_height;
 	  child_allocation.y = y;
 	  
+	  if(layout != GTK_BUTTONBOX_HETEROGENOUS)
+	    {
+	      child_allocation.width = child_width; 
+	    }
+	  else /* if layout will be hetergenous */
+	    {
+	      gint child_hwidth = 0;
+	      GtkRequisition treq;
+	      gint child_xpad = 0;
+
+	      gtk_widget_get_child_requisition( child->widget, &(treq) );
+	      child_hwidth += treq.width;      
+
+	      gtk_widget_style_get(widget, 
+				   "child-internal-pad-x", 
+				   &child_xpad, NULL);
+	      child_hwidth += (child_xpad*2);
+	         
+	      child_allocation.width =  child_hwidth;
+	      childspace = child_hwidth + childspacing;
+
+	    }
+	  
+	  /* calculate the horizontal location */
 	  if (child->is_secondary)
 	    {
 	      child_allocation.x = secondary_x;
@@ -304,4 +448,104 @@
 	}
     }
 }
+
+/* Function to wrap "hide" and "show" signals to call
+ * osso_gtk_hbutton_box_find_button_detail -function.*/
+static void osso_gtk_hbutton_child_showhide_handler (GtkWidget *widget,
+						     gpointer user_data)
+{
+  osso_gtk_hbutton_box_find_button_detail (widget, GTK_WIDGET (user_data), NULL);
+}
   
+/* Function to remove "show"&"hide" signal handlers
+ * from a child when it's removed. */
+static void osso_gtk_hbutton_box_remove_child_signal_handlers (GtkHButtonBox *hbbox,
+							       GtkWidget *removed_widget,
+							       gpointer data)
+{
+  g_signal_handlers_disconnect_by_func (G_OBJECT (removed_widget), osso_gtk_hbutton_box_find_button_detail, hbbox);
+}
+
+/* Signal handler called when we have to set
+ * painting detail values for buttons in this 
+ * gtk_horizontal_button_box.
+ */  
+static void osso_gtk_hbutton_box_find_button_detail (GtkHButtonBox *hbbox,
+					      GtkWidget *addremovewidget,
+					      gpointer data)
+{
+  GList *child;
+  gint visible_buttons = 0;
+  gint secondary_buttons = 0;
+  GtkWidget *leftmost_button = NULL;
+  GtkWidget *rightmost_button = NULL;
+
+  for( child = GTK_BOX (hbbox)->children ; child ; child = child->next ) 
+    {
+      GtkBoxChild *box_child = child->data;
+      GtkWidget *child_widget = box_child->widget;
+      gulong signal_handler = g_signal_handler_find ( G_OBJECT( child_widget ),
+						      G_SIGNAL_MATCH_FUNC,
+						      0, 0, NULL,
+						      G_CALLBACK (osso_gtk_hbutton_child_showhide_handler),
+						      NULL);
+
+      if (signal_handler == 0)
+	{
+	  g_signal_connect_object ( G_OBJECT( child_widget ), 
+				    "hide", 
+				    G_CALLBACK ( osso_gtk_hbutton_child_showhide_handler ), 
+				    hbbox, G_CONNECT_SWAPPED);
+	  g_signal_connect_object ( G_OBJECT( child_widget ), 
+				    "show", 
+				    G_CALLBACK ( osso_gtk_hbutton_child_showhide_handler ), 
+				    hbbox, G_CONNECT_SWAPPED);
+	}
+
+      if ((GTK_WIDGET_VISIBLE (child_widget)) &&
+         (GTK_IS_BUTTON (child_widget)))
+	visible_buttons++;
+      else
+	continue;
+
+      if (leftmost_button == NULL)
+	leftmost_button = child_widget;
+
+      if (secondary_buttons == 0)
+	rightmost_button = child_widget;
+      else 
+	if (box_child->is_secondary)
+	  {
+	    rightmost_button = child_widget;
+	    secondary_buttons++;
+	  }
+
+      if (box_child->is_secondary) 
+        rightmost_button = child_widget;
+    }
+
+  if (visible_buttons == 0)
+    return;
+
+  for( child = GTK_BOX (hbbox)->children ; child ; child = child->next ) 
+    {
+      GtkBoxChild *box_child = child->data;
+      GtkWidget *child_widget = box_child->widget;
+      OssoGtkButtonAttachFlags attachflags = OSSO_GTK_BUTTON_ATTACH_NORTH | OSSO_GTK_BUTTON_ATTACH_SOUTH;
+      gboolean automatic_detail;
+
+      if (!((GTK_WIDGET_VISIBLE (child_widget)) &&
+	  (GTK_IS_BUTTON (child_widget))))
+	continue;
+
+      if (child_widget == leftmost_button)
+	attachflags |= OSSO_GTK_BUTTON_ATTACH_WEST;
+
+      if (child_widget == rightmost_button)
+	attachflags |= OSSO_GTK_BUTTON_ATTACH_EAST;
+
+      g_object_get (G_OBJECT (child_widget), "automatic_detail", &automatic_detail, NULL);
+      if (automatic_detail == TRUE)
+        g_object_set (G_OBJECT (child_widget), "detail", osso_gtk_button_attach_details[attachflags], NULL);
+    }
+}