1 --- gtk+-2.6.4/gtk/gtkdialog.c 2005-01-20 21:52:15.000000000 +0200
2 +++ gtk+-2.6.4/gtk/gtkdialog.c 2005-04-06 16:19:36.416002288 +0300
4 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
7 +/* Modified for Nokia Oyj during 2002-2003. See CHANGES file for list
12 #include "gtkbutton.h"
16 #include "gtkbindings.h"
17 +#include "gtkalignment.h"
19 #define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_DIALOG, GtkDialogPrivate))
22 guint ignore_separator : 1;
27 typedef struct _ResponseData ResponseData;
29 static void gtk_dialog_close (GtkDialog *dialog);
31 static ResponseData* get_response_data (GtkWidget *widget,
35 +static gboolean gtk_dialog_handle_focus (GtkWidget *widget,
36 + GtkDirectionType dir,
37 + gpointer user_data);
39 +static gboolean gtk_dialog_move_to_next_active_button (GList *iter,
42 +static GtkWidget *gtk_dialog_get_first_sensitive (GList *list);
43 +static GtkWidget *gtk_dialog_get_last_sensitive (GList *list);
52 + gtk_widget_class_install_style_property (widget_class,
53 + g_param_spec_int ("extended_left_border",
54 + _("Content area extra left border"),
55 + _("Width of extra left border around the main dialog area"),
60 + gtk_widget_class_install_style_property (widget_class,
61 + g_param_spec_int ("extended_right_border",
62 + _("Content area extra right border"),
63 + _("Width of extra right border around the main dialog area"),
69 binding_set = gtk_binding_set_by_class (class);
71 gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0,
73 update_spacings (GtkDialog *dialog)
77 + GtkWidget *left_padding;
78 + GtkWidget *right_padding;
79 gint content_area_border;
81 gint action_area_border;
83 + gint extended_left_border;
84 + gint extended_right_border;
86 widget = GTK_WIDGET (dialog);
92 + "extended_left_border",
93 + &extended_left_border,
94 + "extended_right_border",
95 + &extended_right_border,
98 gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox),
101 gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area),
104 + if ((extended_left_border == 0) && (extended_right_border == 0))
105 + /* no extended borders, so we are done */
108 + /* extended borders are in use, so reconstruct dialog */
109 + hbox = gtk_hbox_new(FALSE, 0);
110 + left_padding = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
111 + right_padding = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
112 + gtk_widget_set_size_request(left_padding, extended_left_border, 0);
113 + gtk_widget_set_size_request(right_padding, extended_right_border, 0);
115 + gtk_widget_ref(dialog->vbox);
116 + gtk_container_remove(GTK_CONTAINER(dialog), dialog->vbox);
117 + gtk_container_add(GTK_CONTAINER(hbox), left_padding);
118 + gtk_container_add(GTK_CONTAINER(hbox), dialog->vbox);
119 + gtk_container_add(GTK_CONTAINER(hbox), right_padding);
120 + gtk_container_add(GTK_CONTAINER(dialog), hbox);
121 + gtk_widget_unref(dialog->vbox);
123 + gtk_widget_show(left_padding);
124 + gtk_widget_show(right_padding);
125 + gtk_widget_show(hbox);
129 gtk_dialog_init (GtkDialog *dialog)
131 GtkDialogPrivate *priv;
132 + GtkWidget *alignment;
134 priv = GET_PRIVATE (dialog);
135 priv->ignore_separator = FALSE;
136 @@ -250,14 +318,23 @@
137 gtk_container_add (GTK_CONTAINER (dialog), dialog->vbox);
138 gtk_widget_show (dialog->vbox);
140 + /* Hildon : Here we add an alignment widget to gtk because
141 + * we want that the dialog buttons are all centered. */
142 + alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
143 + gtk_box_pack_end (GTK_BOX (dialog->vbox), alignment, FALSE, TRUE, 0);
145 dialog->action_area = gtk_hbutton_box_new ();
147 gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog->action_area),
150 - gtk_box_pack_end (GTK_BOX (dialog->vbox), dialog->action_area,
152 + /* we need add-signal to allocate correct area for childs */
153 + gtk_container_add (GTK_CONTAINER (alignment), dialog->action_area);
154 + /* gtk_box_pack_end (GTK_BOX (dialog->vbox), dialog->action_area,
155 + FALSE, TRUE, 0); */
157 gtk_widget_show (dialog->action_area);
158 + gtk_widget_show (alignment);
160 dialog->separator = gtk_hseparator_new ();
161 gtk_box_pack_end (GTK_BOX (dialog->vbox), dialog->separator, FALSE, TRUE, 0);
164 g_warning ("Only 'activatable' widgets can be packed into the action area of a GtkDialog");
166 + gtk_container_add(GTK_CONTAINER(dialog->action_area), child);
168 gtk_box_pack_end (GTK_BOX (dialog->action_area),
173 + g_signal_connect (child, "focus",
174 + (GCallback)gtk_dialog_handle_focus, (gpointer)dialog);
176 if (response_id == GTK_RESPONSE_HELP)
177 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (dialog->action_area), child, TRUE);
181 * Return value: the button widget that was added
185 gtk_dialog_add_button (GtkDialog *dialog,
186 const gchar *button_text,
188 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
190 gtk_widget_show (button);
193 + g_signal_connect (button, "focus",
194 + (GCallback)gtk_dialog_handle_focus,
196 gtk_dialog_add_action_widget (dialog,
200 gulong unmap_handler;
201 gulong destroy_handler;
202 gulong delete_handler;
203 + GtkDialogPrivate *priv;
204 + GList *list = NULL;
206 g_return_val_if_fail (GTK_IS_DIALOG (dialog), -1);
208 @@ -1001,6 +1089,27 @@
210 if (!GTK_WIDGET_VISIBLE (dialog))
211 gtk_widget_show (GTK_WIDGET (dialog));
213 + priv = GET_PRIVATE (dialog);
214 + list = gtk_container_get_children (GTK_CONTAINER (dialog->vbox));
215 + priv->first = gtk_dialog_get_first_sensitive (list);
216 + priv->last = gtk_dialog_get_last_sensitive (list);
220 + g_signal_connect (priv->first, "focus",
221 + (GCallback)gtk_dialog_handle_focus,
227 + g_signal_connect (priv->last, "focus",
228 + (GCallback)gtk_dialog_handle_focus,
232 + g_list_free (list);
235 g_signal_connect (dialog,
236 @@ -1236,4 +1345,215 @@
237 gtk_box_reorder_child (GTK_BOX (dialog->action_area), child, position);
241 +gtk_dialog_handle_focus (GtkWidget *widget,
242 + GtkDirectionType dir,
243 + gpointer user_data)
245 + GtkDialog *dialog = NULL;
246 + GList *list = NULL;
247 + GList *iter = NULL;
249 + gint list_length = 0;
250 + gboolean ret_val = FALSE;
251 + GtkDialogPrivate *priv;
253 + dialog = GTK_DIALOG(user_data);
254 + list = gtk_container_get_children (GTK_CONTAINER(
255 + GTK_DIALOG(user_data)->action_area));
257 + priv = GET_PRIVATE (dialog);
259 + if (GTK_WIDGET_HAS_FOCUS (widget))
260 + if (widget == priv->first)
262 + if (dir == GTK_DIR_UP)
264 + ret_val = gtk_dialog_move_to_next_active_button (g_list_last (list),
267 + else if (dir == GTK_DIR_DOWN && priv->first == priv->last)
268 + ret_val = gtk_dialog_move_to_next_active_button (list, TRUE);
269 + else if (dir == GTK_DIR_DOWN)
273 + else if (widget == priv->last)
275 + if (dir == GTK_DIR_DOWN)
277 + ret_val = gtk_dialog_move_to_next_active_button (list, TRUE);
279 + else if (dir == GTK_DIR_UP)
285 + list_length = g_list_length(list);
286 + while (iter != NULL)
289 + if (iter->data == widget)
293 + /* If in the first item -> the default works like it should */
297 + /* If not in the first button, but in the first active
298 + * button, the default should do, else handle movement
301 + ret_val = gtk_dialog_move_to_next_active_button (
302 + g_list_previous (iter),
307 + /* gtk_widget_grab_focus (priv->last);*/
308 + g_signal_emit_by_name (dialog, "move-focus",
309 + GTK_DIR_TAB_BACKWARD);
314 + /* If in the last item:jump to top, else select previous button */
316 + if (i < list_length)
318 + ret_val = gtk_dialog_move_to_next_active_button (
319 + g_list_next (iter),
323 + g_signal_emit_by_name (dialog, "move-focus",
324 + GTK_DIR_TAB_FORWARD);
330 + g_signal_emit_by_name (dialog, "move-focus",
331 + GTK_DIR_TAB_FORWARD);
336 + case GTK_DIR_TAB_BACKWARD:
337 + case GTK_DIR_TAB_FORWARD:
339 + case GTK_DIR_RIGHT:
345 + iter = g_list_next(iter);
349 + g_list_free (list);
354 +gtk_dialog_move_to_next_active_button (GList *iter, gboolean forward)
361 + g_object_get (G_OBJECT (iter->data), "sensitive", &active, NULL);
362 + g_object_get (G_OBJECT (iter->data), "visible", &visible, NULL);
363 + if (active && visible)
365 + gtk_widget_grab_focus (GTK_WIDGET (iter->data));
370 + iter = g_list_next (iter);
372 + iter = g_list_previous (iter);
378 +gtk_dialog_get_first_sensitive (GList *list)
380 + GList *sublist = NULL;
381 + GList *iter = NULL;
382 + GtkWidget *widget = NULL;
387 + widget = GTK_WIDGET (list->data);
388 + if (GTK_IS_CONTAINER (widget))
390 + sublist = gtk_container_get_children (GTK_CONTAINER(widget));
391 + widget = gtk_dialog_get_first_sensitive (sublist);
392 + g_list_free (sublist);
400 + g_object_get (G_OBJECT (widget), "sensitive", &active, NULL);
401 + g_object_get (G_OBJECT (widget), "visible", &visible, NULL);
402 + if (active && visible && GTK_WIDGET_CAN_FOCUS (widget))
406 + list = g_list_next (list);
413 +gtk_dialog_get_last_sensitive (GList *list)
415 + GList *sublist = NULL;
416 + GtkWidget *widget = NULL;
420 + list = g_list_last (list);
421 + if (list && list->prev != NULL)
422 + list = g_list_previous (list);
426 + widget = GTK_WIDGET (list->data);
427 + if (GTK_IS_CONTAINER (widget))
429 + sublist = gtk_container_get_children (GTK_CONTAINER(widget));
430 + widget = gtk_dialog_get_last_sensitive (sublist);
431 + g_list_free (sublist);
439 + g_object_get (G_OBJECT (widget), "sensitive", &active, NULL);
440 + g_object_get (G_OBJECT (widget), "visible", &visible, NULL);
441 + if (active && visible && GTK_WIDGET_CAN_FOCUS (widget))
445 + list = g_list_previous (list);