452 lines
13 KiB
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;
|
|
+}
|
|
+
|
|
|