generic-poky/openembedded/packages/gtk+/gtk+-2.6.4-1.osso7/gtkdialog.c.diff

452 lines
13 KiB
Diff

--- 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;
+}
+