--- gtk+-2.6.4/gtk/gtkdialog.c	2005-01-20 21:52:15.000000000 +0200
+++ gtk+-2.6.4/gtk/gtkdialog.c	2005-04-06 16:19:36.416002288 +0300
@@ -24,6 +24,9 @@
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+/* Modified for Nokia Oyj during 2002-2003. See CHANGES file for list
+ * of changes.
+ */
 #include <config.h>
 #include "gtkalias.h"
 #include "gtkbutton.h"
@@ -37,11 +40,14 @@
 #include "gtkmain.h"
 #include "gtkintl.h"
 #include "gtkbindings.h"
+#include "gtkalignment.h"
 
 #define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_DIALOG, GtkDialogPrivate))
 
 typedef struct {
   guint ignore_separator : 1;
+  GtkWidget *first;
+  GtkWidget *last;
 } GtkDialogPrivate;
 
 typedef struct _ResponseData ResponseData;
@@ -77,7 +83,18 @@
 static void gtk_dialog_close             (GtkDialog        *dialog);
 
 static ResponseData* get_response_data   (GtkWidget        *widget,
-					  gboolean          create);
+                                          gboolean          create);
+
+static gboolean gtk_dialog_handle_focus (GtkWidget *widget,
+                                         GtkDirectionType dir,
+                                         gpointer user_data);
+
+static gboolean gtk_dialog_move_to_next_active_button (GList *iter,
+                                                       gboolean forward);
+
+static GtkWidget *gtk_dialog_get_first_sensitive (GList *list);
+static GtkWidget *gtk_dialog_get_last_sensitive (GList *list);
+
 
 enum {
   PROP_0,
@@ -195,6 +212,23 @@
                                                              5,
                                                              G_PARAM_READABLE));
 
+  gtk_widget_class_install_style_property (widget_class,
+                                           g_param_spec_int ("extended_left_border",
+                                                             _("Content area extra left border"),
+                                                             _("Width of extra left border around the main dialog area"),
+                                                             0,
+                                                             G_MAXINT,
+                                                             0,
+                                                             G_PARAM_READABLE));
+  gtk_widget_class_install_style_property (widget_class,
+                                           g_param_spec_int ("extended_right_border",
+                                                             _("Content area extra right border"),
+                                                             _("Width of extra right border around the main dialog area"),
+                                                             0,
+                                                             G_MAXINT,
+                                                             0,
+                                                             G_PARAM_READABLE));
+
   binding_set = gtk_binding_set_by_class (class);
   
   gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0,
@@ -205,9 +239,15 @@
 update_spacings (GtkDialog *dialog)
 {
   GtkWidget *widget;
+  GtkWidget *hbox;
+  GtkWidget *left_padding;
+  GtkWidget *right_padding;
   gint content_area_border;
   gint button_spacing;
   gint action_area_border;
+
+	gint extended_left_border;
+  gint extended_right_border;
   
   widget = GTK_WIDGET (dialog);
 
@@ -218,6 +258,10 @@
                         &button_spacing,
                         "action_area_border",
                         &action_area_border,
+	"extended_left_border",
+	&extended_left_border,
+	"extended_right_border",
+	&extended_right_border,
                         NULL);
 
   gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox),
@@ -226,12 +270,36 @@
                        button_spacing);
   gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area),
                                   action_area_border);
+
+  if ((extended_left_border == 0) && (extended_right_border == 0))
+    /* no extended borders, so we are done */
+    return;
+
+  /* extended borders are in use, so reconstruct dialog */
+  hbox = gtk_hbox_new(FALSE, 0);
+  left_padding = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
+  right_padding = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
+  gtk_widget_set_size_request(left_padding, extended_left_border, 0);
+  gtk_widget_set_size_request(right_padding, extended_right_border, 0);
+
+  gtk_widget_ref(dialog->vbox);
+  gtk_container_remove(GTK_CONTAINER(dialog), dialog->vbox);
+  gtk_container_add(GTK_CONTAINER(hbox), left_padding);
+  gtk_container_add(GTK_CONTAINER(hbox), dialog->vbox);
+  gtk_container_add(GTK_CONTAINER(hbox), right_padding);
+  gtk_container_add(GTK_CONTAINER(dialog), hbox);
+  gtk_widget_unref(dialog->vbox);
+
+  gtk_widget_show(left_padding);
+  gtk_widget_show(right_padding);
+  gtk_widget_show(hbox);
 }
 
 static void
 gtk_dialog_init (GtkDialog *dialog)
 {
   GtkDialogPrivate *priv;
+  GtkWidget *alignment;
 
   priv = GET_PRIVATE (dialog);
   priv->ignore_separator = FALSE;
@@ -250,14 +318,23 @@
   gtk_container_add (GTK_CONTAINER (dialog), dialog->vbox);
   gtk_widget_show (dialog->vbox);
 
+  /* Hildon : Here we add an alignment widget to gtk because
+   * we want that the dialog buttons are all centered. */
+  alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
+  gtk_box_pack_end (GTK_BOX (dialog->vbox), alignment, FALSE, TRUE, 0);
+
   dialog->action_area = gtk_hbutton_box_new ();
 
   gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog->action_area),
                              GTK_BUTTONBOX_END);  
 
-  gtk_box_pack_end (GTK_BOX (dialog->vbox), dialog->action_area,
-                    FALSE, TRUE, 0);
+  /* we need add-signal to allocate correct area for childs */ 
+  gtk_container_add (GTK_CONTAINER (alignment), dialog->action_area);
+  /* gtk_box_pack_end (GTK_BOX (dialog->vbox), dialog->action_area,
+     FALSE, TRUE, 0); */
+  
   gtk_widget_show (dialog->action_area);
+  gtk_widget_show (alignment);
 
   dialog->separator = gtk_hseparator_new ();
   gtk_box_pack_end (GTK_BOX (dialog->vbox), dialog->separator, FALSE, TRUE, 0);
@@ -616,9 +693,15 @@
   else
     g_warning ("Only 'activatable' widgets can be packed into the action area of a GtkDialog");
 
+  gtk_container_add(GTK_CONTAINER(dialog->action_area), child);
+/*
   gtk_box_pack_end (GTK_BOX (dialog->action_area),
                     child,
                     FALSE, TRUE, 0);
+*/  
+
+  g_signal_connect (child, "focus", 
+                    (GCallback)gtk_dialog_handle_focus, (gpointer)dialog);
   
   if (response_id == GTK_RESPONSE_HELP)
     gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (dialog->action_area), child, TRUE);
@@ -637,7 +720,7 @@
  * you don't need it.
  *
  * Return value: the button widget that was added
- **/
+ **/ /*ROK*/
 GtkWidget*
 gtk_dialog_add_button (GtkDialog   *dialog,
                        const gchar *button_text,
@@ -653,7 +736,10 @@
   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
   
   gtk_widget_show (button);
-  
+
+  g_signal_connect (button, "focus", 
+                   (GCallback)gtk_dialog_handle_focus,
+                   (gpointer)dialog);
   gtk_dialog_add_action_widget (dialog,
                                 button,
                                 response_id);
@@ -990,6 +1076,8 @@
   gulong unmap_handler;
   gulong destroy_handler;
   gulong delete_handler;
+  GtkDialogPrivate *priv;
+  GList *list = NULL;
   
   g_return_val_if_fail (GTK_IS_DIALOG (dialog), -1);
 
@@ -1001,6 +1089,27 @@
 
   if (!GTK_WIDGET_VISIBLE (dialog))
     gtk_widget_show (GTK_WIDGET (dialog));
+
+  priv = GET_PRIVATE (dialog);
+  list = gtk_container_get_children (GTK_CONTAINER (dialog->vbox));
+  priv->first = gtk_dialog_get_first_sensitive (list);
+  priv->last = gtk_dialog_get_last_sensitive (list);
+  
+  if (priv->first)
+  {
+      g_signal_connect (priv->first, "focus",
+                        (GCallback)gtk_dialog_handle_focus,
+                        (gpointer)dialog);
+  }
+  
+  if (priv->last)
+  {
+      g_signal_connect (priv->last, "focus",
+                        (GCallback)gtk_dialog_handle_focus,
+                        (gpointer)dialog);
+  }
+
+  g_list_free (list);
   
   response_handler =
     g_signal_connect (dialog,
@@ -1236,4 +1345,215 @@
       gtk_box_reorder_child (GTK_BOX (dialog->action_area), child, position);
     }
 }
+static gboolean
+gtk_dialog_handle_focus (GtkWidget *widget,
+                          GtkDirectionType dir,
+                          gpointer user_data)
+ {
+   GtkDialog *dialog = NULL;
+   GList *list = NULL;
+   GList *iter = NULL;
+   gint i = 0;
+   gint list_length = 0;
+   gboolean ret_val = FALSE;
+   GtkDialogPrivate *priv;
+
+   dialog = GTK_DIALOG(user_data);
+   list = gtk_container_get_children (GTK_CONTAINER(
+                                       GTK_DIALOG(user_data)->action_area));
+   iter = list;
+   priv = GET_PRIVATE (dialog);
+
+   if (GTK_WIDGET_HAS_FOCUS (widget))
+   if (widget == priv->first)
+   {
+     if (dir == GTK_DIR_UP)
+     {
+       ret_val = gtk_dialog_move_to_next_active_button (g_list_last (list),
+                                                      FALSE);
+     }
+     else if (dir == GTK_DIR_DOWN && priv->first == priv->last)
+         ret_val = gtk_dialog_move_to_next_active_button (list, TRUE);
+     else if  (dir == GTK_DIR_DOWN)
+     {
+     }
+   }
+   else if (widget == priv->last)
+   {
+     if (dir == GTK_DIR_DOWN)
+     {
+       ret_val = gtk_dialog_move_to_next_active_button (list, TRUE);
+     }
+     else if (dir == GTK_DIR_UP)
+     {
+     }
+   }
+   else
+   {
+	   list_length =  g_list_length(list);
+	   while (iter != NULL)
+	   {
+		   ++i;
+		   if (iter->data == widget)
+		   {
+			   switch (dir) {
+				   case GTK_DIR_UP:
+					   /* If in the first item -> the default works like it should */
+
+					   if (i > 1)
+					   {
+						   /* If not in the first button, but in the first active
+						    * button, the default should do, else handle movement
+						    * by yourself
+						    */
+						   ret_val = gtk_dialog_move_to_next_active_button (
+								   g_list_previous (iter),
+								   FALSE);
+					   }
+					   else
+					   {
+						   /* gtk_widget_grab_focus (priv->last);*/
+						   g_signal_emit_by_name (dialog, "move-focus",
+								   GTK_DIR_TAB_BACKWARD);
+						   ret_val = TRUE;
+					   }
+					   break;
+
+					   /* If in the last item:jump to top, else select previous button */
+				   case GTK_DIR_DOWN:
+					   if (i < list_length)
+					   {
+						   ret_val = gtk_dialog_move_to_next_active_button (
+								   g_list_next (iter),
+								   TRUE);
+						   if (!ret_val)
+						   {
+							   g_signal_emit_by_name (dialog, "move-focus",
+									   GTK_DIR_TAB_FORWARD);
+							   ret_val = TRUE;
+						   }
+					   }
+					   else
+					   {
+						   g_signal_emit_by_name (dialog, "move-focus",
+								   GTK_DIR_TAB_FORWARD);
+						   ret_val = TRUE;
+					   }
+					   break;
+
+				   case GTK_DIR_TAB_BACKWARD:
+				   case GTK_DIR_TAB_FORWARD:
+				   case GTK_DIR_LEFT:
+				   case GTK_DIR_RIGHT:
+				   default:
+					   break;
+			   }
+			   break;
+		   }
+		   iter = g_list_next(iter);
+	   }
+   }
+
+   g_list_free (list);
+
+   return ret_val;
+ }
+static gboolean
+gtk_dialog_move_to_next_active_button (GList *iter, gboolean forward)
+{
+	gboolean active;
+	gboolean visible;
+
+	while (iter)
+	{
+		g_object_get (G_OBJECT (iter->data), "sensitive", &active, NULL);
+		g_object_get (G_OBJECT (iter->data), "visible", &visible, NULL);
+		if (active && visible)
+		{
+			gtk_widget_grab_focus (GTK_WIDGET (iter->data));
+			return TRUE;
+		}
+
+		if (forward)
+			iter = g_list_next (iter);
+		else
+			iter = g_list_previous (iter);
+	}
+
+	return FALSE;
+}
+static GtkWidget*
+gtk_dialog_get_first_sensitive (GList *list)
+{
+	GList *sublist = NULL;
+	GList *iter = NULL;
+	GtkWidget *widget = NULL;
+	gboolean active;
+	gboolean visible;
+	while (list)
+	{
+		widget = GTK_WIDGET (list->data);
+		if (GTK_IS_CONTAINER (widget))
+		{
+			sublist = gtk_container_get_children (GTK_CONTAINER(widget));
+			widget = gtk_dialog_get_first_sensitive (sublist);
+			g_list_free (sublist);
+			sublist = NULL;
+
+			if (widget)
+				return widget;
+		}
+		else
+		{
+			g_object_get (G_OBJECT (widget), "sensitive", &active, NULL);
+			g_object_get (G_OBJECT (widget), "visible", &visible, NULL);
+			if (active && visible && GTK_WIDGET_CAN_FOCUS (widget))
+				return widget;
+		}
+
+		list = g_list_next (list);
+	}
+
+	return NULL;
+}
+
+static GtkWidget*
+gtk_dialog_get_last_sensitive (GList *list)
+{
+	GList *sublist = NULL;
+	GtkWidget *widget = NULL;
+	gboolean active;
+	gboolean visible;
+
+	list = g_list_last (list);
+	if (list && list->prev != NULL)
+		list = g_list_previous (list);
+
+	while (list)
+	{
+		widget = GTK_WIDGET (list->data);
+		if (GTK_IS_CONTAINER (widget))
+		{
+			sublist = gtk_container_get_children (GTK_CONTAINER(widget));
+			widget = gtk_dialog_get_last_sensitive (sublist);
+			g_list_free (sublist);
+			sublist = NULL;
+
+			if (widget)
+				return widget;
+		}
+		else
+		{
+			g_object_get (G_OBJECT (widget), "sensitive", &active, NULL);
+			g_object_get (G_OBJECT (widget), "visible", &visible, NULL);
+			if (active && visible && GTK_WIDGET_CAN_FOCUS (widget))
+				return widget;
+		}
+
+		list = g_list_previous (list);
+	}
+
+	return NULL;
+}
+