diff options
-rw-r--r-- | ChangeLog | 36 | ||||
-rw-r--r-- | gtk/gtkfilechooserdefault.c | 130 | ||||
-rw-r--r-- | gtk/gtkfilechooserdialog.c | 162 | ||||
-rw-r--r-- | gtk/gtkfilechooserembed.c | 28 | ||||
-rw-r--r-- | gtk/gtkfilechooserembed.h | 9 | ||||
-rw-r--r-- | gtk/gtkfilechooserprivate.h | 7 |
6 files changed, 160 insertions, 212 deletions
@@ -1,5 +1,41 @@ 2007-05-18 Carlos Garnacho <carlos@imendio.com> + Refactor GtkFileChooserDialog sizing. + + * gtkfilechooserembed.[ch] (delegate_get_resizable_hints) + (_gtk_file_chooser_embed_get_resizable_hints): + s/resizable_hints/resizable/, return just one boolean value to + determine whether the filechooser should be resizable or not. + + * gtkfilechooserprivate.h (struct GtkFileChooserDialogPrivate): remove + variables related to the GtkFileChooserEmbed get_default_size() and + get_resizable() implementations. + (struct GtkFileChooserDefault): Move default size management here. + + * gtkfilechooserdefault.c (gtk_file_chooser_default_size_allocate): + Added, store currently allocated size to calculate default size later. + (gtk_file_chooser_default_get_resizable_hints): + s/resizable_hints/resizable/. + (gtk_file_chooser_default_set_property): Reload settings if the file + chooser action changes, this way the save expander state will be known + before mapping the window, avoiding wrong window positioning and + flickering. (#424299, #424309) + (find_good_size_from_style): Only get size from style if it wasn't set + previously. + (gtk_file_chooser_default_get_default_size): return default size based + on stored default size and preview/extra widget sizes. + + * gtkfilechooserdialog.c (file_chooser_widget_update_hints) + (file_chooser_widget_realized_size_changed) + (file_chooser_widget_unrealized_size_changed): simplified to + (file_chooser_widget_size_changed): set window size and resizability + based on the GtkFileChooserEmbed interface implementation. (Bug + #420285, Tomeu Vizoso) + (gtk_file_chooser_dialog_map): force a dialog size change, so it's + clamped for sure to the 75% of the screen size. + +2007-05-18 Carlos Garnacho <carlos@imendio.com> + * gtk/gtknotebook.c (gtk_notebook_real_insert_page): Do not unset the brand new current page if there was none set previously. Fixes #425138 (Reported by Michail Crayson). Some code simplifications. diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c index 7dd24f4a1c..5daafabc5e 100644 --- a/gtk/gtkfilechooserdefault.c +++ b/gtk/gtkfilechooserdefault.c @@ -324,6 +324,8 @@ static void gtk_file_chooser_default_style_set (GtkWidget * GtkStyle *previous_style); static void gtk_file_chooser_default_screen_changed (GtkWidget *widget, GdkScreen *previous_screen); +static void gtk_file_chooser_default_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); static gboolean gtk_file_chooser_default_set_current_folder (GtkFileChooser *chooser, const GtkFilePath *path, @@ -362,9 +364,7 @@ static GSList * gtk_file_chooser_default_list_shortcut_folders (GtkFileCh static void gtk_file_chooser_default_get_default_size (GtkFileChooserEmbed *chooser_embed, gint *default_width, gint *default_height); -static void gtk_file_chooser_default_get_resizable_hints (GtkFileChooserEmbed *chooser_embed, - gboolean *resize_horizontally, - gboolean *resize_vertically); +static gboolean gtk_file_chooser_default_get_resizable (GtkFileChooserEmbed *chooser_embed); static gboolean gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed); static void gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed); @@ -487,6 +487,7 @@ static void search_switch_to_browse_mode (GtkFileChooserDefault *impl); static GSList *search_get_selected_paths (GtkFileChooserDefault *impl); static void search_entry_activate_cb (GtkEntry *entry, gpointer data); +static void settings_load (GtkFileChooserDefault *impl); static void search_get_valid_child_iter (GtkFileChooserDefault *impl, GtkTreeIter *child_iter, GtkTreeIter *iter); @@ -613,6 +614,7 @@ _gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class) widget_class->hierarchy_changed = gtk_file_chooser_default_hierarchy_changed; widget_class->style_set = gtk_file_chooser_default_style_set; widget_class->screen_changed = gtk_file_chooser_default_screen_changed; + widget_class->size_allocate = gtk_file_chooser_default_size_allocate; signals[LOCATION_POPUP] = _gtk_binding_signal_new (I_("location-popup"), @@ -811,7 +813,7 @@ static void gtk_file_chooser_embed_default_iface_init (GtkFileChooserEmbedIface *iface) { iface->get_default_size = gtk_file_chooser_default_get_default_size; - iface->get_resizable_hints = gtk_file_chooser_default_get_resizable_hints; + iface->get_resizable = gtk_file_chooser_default_get_resizable; iface->should_respond = gtk_file_chooser_default_should_respond; iface->initial_focus = gtk_file_chooser_default_initial_focus; } @@ -5473,6 +5475,7 @@ gtk_file_chooser_default_set_property (GObject *object, } impl->action = action; update_appearance (impl); + settings_load (impl); } } break; @@ -5917,6 +5920,37 @@ gtk_file_chooser_default_screen_changed (GtkWidget *widget, profile_end ("end", NULL); } +static void +gtk_file_chooser_default_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkFileChooserDefault *impl; + + impl = GTK_FILE_CHOOSER_DEFAULT (widget); + + GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->size_allocate (widget, allocation); + + if (!gtk_file_chooser_default_get_resizable (GTK_FILE_CHOOSER_EMBED (impl))) + { + /* The dialog is not resizable, we shouldn't + * trust in the size it has in this stage + */ + return; + } + + impl->default_width = allocation->width; + impl->default_height = allocation->height; + + if (impl->preview_widget_active && + impl->preview_widget && + GTK_WIDGET_DRAWABLE (impl->preview_widget)) + impl->default_width -= impl->preview_widget->allocation.width + PREVIEW_HBOX_SPACING; + + if (impl->extra_widget && + GTK_WIDGET_DRAWABLE (impl->extra_widget)) + impl->default_height -= GTK_BOX (widget)->spacing + impl->extra_widget->allocation.height; +} + static gboolean get_is_file_filtered (GtkFileChooserDefault *impl, const GtkFilePath *path, @@ -7760,49 +7794,35 @@ find_good_size_from_style (GtkWidget *widget, gint *height) { GtkFileChooserDefault *impl; - gint default_width, default_height; int font_size; - GtkRequisition req; GdkScreen *screen; double resolution; g_assert (widget->style != NULL); impl = GTK_FILE_CHOOSER_DEFAULT (widget); - screen = gtk_widget_get_screen (widget); - if (screen) + if (impl->default_width == 0 && + impl->default_height == 0) { - resolution = gdk_screen_get_resolution (screen); - if (resolution < 0.0) /* will be -1 if the resolution is not defined in the GdkScreen */ - resolution = 96.0; - } - else - resolution = 96.0; /* wheeee */ - - font_size = pango_font_description_get_size (widget->style->font_desc); - font_size = PANGO_PIXELS (font_size) * resolution / 72.0; + screen = gtk_widget_get_screen (widget); + if (screen) + { + resolution = gdk_screen_get_resolution (screen); + if (resolution < 0.0) /* will be -1 if the resolution is not defined in the GdkScreen */ + resolution = 96.0; + } + else + resolution = 96.0; /* wheeee */ - default_width = font_size * NUM_CHARS; - default_height = font_size * NUM_LINES; + font_size = pango_font_description_get_size (widget->style->font_desc); + font_size = PANGO_PIXELS (font_size) * resolution / 72.0; - if (impl->preview_widget_active && impl->preview_widget) - { - gtk_widget_size_request (impl->preview_box, &req); - default_width += PREVIEW_HBOX_SPACING + req.width; + impl->default_width = font_size * NUM_CHARS; + impl->default_height = font_size * NUM_LINES; } - if (impl->extra_widget) - { - gtk_widget_size_request (impl->extra_align, &req); - default_height += GTK_BOX (widget)->spacing + req.height; - } - - gtk_widget_size_request (widget, &req); - default_width = MAX (default_width, req.width); - default_height = MAX (default_height, req.height); - - *width = default_width; - *height = default_height; + *width = impl->default_width; + *height = impl->default_height; } static void @@ -7811,35 +7831,37 @@ gtk_file_chooser_default_get_default_size (GtkFileChooserEmbed *chooser_embed, gint *default_height) { GtkFileChooserDefault *impl; + GtkRequisition req; impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); find_good_size_from_style (GTK_WIDGET (chooser_embed), default_width, default_height); + + if (impl->preview_widget_active && + impl->preview_widget && + GTK_WIDGET_VISIBLE (impl->preview_widget)) + { + gtk_widget_size_request (impl->preview_box, &req); + *default_width += PREVIEW_HBOX_SPACING + req.width; + } + + if (impl->extra_widget && + GTK_WIDGET_VISIBLE (impl->extra_widget)) + { + gtk_widget_size_request (impl->extra_align, &req); + *default_height += GTK_BOX (chooser_embed)->spacing + req.height; + } } -static void -gtk_file_chooser_default_get_resizable_hints (GtkFileChooserEmbed *chooser_embed, - gboolean *resize_horizontally, - gboolean *resize_vertically) +static gboolean +gtk_file_chooser_default_get_resizable (GtkFileChooserEmbed *chooser_embed) { GtkFileChooserDefault *impl; - g_return_if_fail (resize_horizontally != NULL); - g_return_if_fail (resize_vertically != NULL); - impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); - *resize_horizontally = TRUE; - *resize_vertically = TRUE; - - if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || - impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) - { - if (! gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander))) - { - *resize_horizontally = FALSE; - *resize_vertically = FALSE; - } - } + return (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || + impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || + gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander))); } struct switch_folder_closure { diff --git a/gtk/gtkfilechooserdialog.c b/gtk/gtkfilechooserdialog.c index 7bdb650e39..5adf8b28fe 100644 --- a/gtk/gtkfilechooserdialog.c +++ b/gtk/gtkfilechooserdialog.c @@ -86,10 +86,6 @@ gtk_file_chooser_dialog_init (GtkFileChooserDialog *dialog) GtkDialog *fc_dialog = GTK_DIALOG (dialog); dialog->priv = priv; - dialog->priv->default_width = -1; - dialog->priv->default_height = -1; - dialog->priv->resize_horizontally = TRUE; - dialog->priv->resize_vertically = TRUE; dialog->priv->response_requested = FALSE; gtk_dialog_set_has_separator (fc_dialog, FALSE); @@ -153,25 +149,6 @@ file_chooser_widget_file_activated (GtkFileChooser *chooser, } static void -file_chooser_widget_update_hints (GtkFileChooserDialog *dialog, - gint width) -{ - GtkFileChooserDialogPrivate *priv; - GdkGeometry geometry; - - priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog); - - geometry.min_width = (!priv->resize_horizontally ? width : -1); - geometry.min_height = -1; - geometry.max_width = (priv->resize_horizontally?G_MAXSHORT:-1); - geometry.max_height = (priv->resize_vertically?G_MAXSHORT:-1); - - gtk_window_set_geometry_hints (GTK_WINDOW (dialog), NULL, - &geometry, - GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE); -} - -static void clamp_to_screen (GtkWidget *widget, gint *width, gint *height) @@ -195,131 +172,57 @@ clamp_to_screen (GtkWidget *widget, } static void -file_chooser_widget_default_realized_size_changed (GtkWidget *widget, - GtkFileChooserDialog *dialog) +file_chooser_widget_default_size_changed (GtkWidget *widget, + GtkFileChooserDialog *dialog) { GtkFileChooserDialogPrivate *priv; - gint width; - gint height; + gint width, height; gint default_width, default_height; - GtkRequisition req; - gboolean resize_horizontally; - gboolean resize_vertically; - gboolean update_hints; - gint dx = 0, dy = 0; - gint cur_width, cur_height; + GtkRequisition req, widget_req; + gboolean resizable; priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog); - /* Force a size request of everything before we start. This will make sure - * that widget->requisition is meaningful. */ - gtk_widget_size_request (GTK_WIDGET (dialog), &req); - gtk_window_get_size (GTK_WINDOW (dialog), &cur_width, &cur_height); - width = GTK_WIDGET (dialog)->requisition.width - priv->widget->requisition.width; - height = GTK_WIDGET (dialog)->requisition.height - priv->widget->requisition.height; - _gtk_file_chooser_embed_get_default_size (GTK_FILE_CHOOSER_EMBED (priv->widget), - &default_width, &default_height); - - /* Ideal target size modulo any resizing */ - width = default_width + width; - height = default_height + height; + /* Unset any previously set size */ + gtk_widget_set_size_request (GTK_WIDGET (dialog), -1, -1); - /* Now, we test for resizability */ - update_hints = FALSE; - _gtk_file_chooser_embed_get_resizable_hints (GTK_FILE_CHOOSER_EMBED (priv->widget), - &resize_horizontally, - &resize_vertically); - resize_vertically = (!! resize_vertically); /* normalize */ - resize_horizontally = (!! resize_horizontally); - - if (resize_horizontally && priv->resize_horizontally) + if (GTK_WIDGET_DRAWABLE (widget)) { - dx = default_width - priv->default_width; - priv->default_width = default_width; - } - else if (resize_horizontally && ! priv->resize_horizontally) - { - /* We restore to the ideal size + any change in default_size (which is not - * expected). It would be nicer to store the older size to restore to in - * the future. */ - dx = default_width - priv->default_width; - dx += width - cur_width; - priv->default_width = default_width; - update_hints = TRUE; - } - else - { - update_hints = TRUE; - } + /* Force a size request of everything before we start. This will make sure + * that widget->requisition is meaningful. */ + gtk_widget_size_request (GTK_WIDGET (dialog), &req); + gtk_widget_size_request (widget, &widget_req); - if (resize_vertically && priv->resize_vertically) - { - dy = default_height - priv->default_height; - priv->default_height = default_height; - } - else if (resize_vertically && ! priv->resize_vertically) - { - dy = default_height - priv->default_height; - dy += height - cur_height; - priv->default_height = default_height; - update_hints = TRUE; + width = req.width - widget_req.width; + height = req.height - widget_req.height; } else { - update_hints = TRUE; + width = GTK_WIDGET (dialog)->allocation.width - widget->allocation.width; + height = GTK_WIDGET (dialog)->allocation.height - widget->allocation.height; } - priv->resize_horizontally = resize_horizontally; - priv->resize_vertically = resize_vertically; - - if (dx != 0 || dy != 0) - { - gint new_width = cur_width + dx; - gint new_height = cur_height + dy; - - clamp_to_screen (GTK_WIDGET (dialog), &new_width, &new_height); - - gtk_window_resize (GTK_WINDOW (dialog), new_width, new_height); - } - - /* Only store the size if we can resize in that direction. */ - if (update_hints) - file_chooser_widget_update_hints (dialog, width); -} - -static void -file_chooser_widget_default_unrealized_size_changed (GtkWidget *widget, - GtkFileChooserDialog *dialog) -{ - GtkFileChooserDialogPrivate *priv; - GtkRequisition req; - gint width, height; - - priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog); - gtk_widget_size_request (GTK_WIDGET (dialog), &req); - - _gtk_file_chooser_embed_get_resizable_hints (GTK_FILE_CHOOSER_EMBED (priv->widget), - &(priv->resize_horizontally), - &(priv->resize_vertically)); + resizable = _gtk_file_chooser_embed_get_resizable (GTK_FILE_CHOOSER_EMBED (priv->widget)); _gtk_file_chooser_embed_get_default_size (GTK_FILE_CHOOSER_EMBED (priv->widget), - &(priv->default_width), &(priv->default_height)); - - /* Determine how much space the rest of the dialog uses compared to priv->widget */ - width = priv->default_width + GTK_WIDGET (dialog)->requisition.width - priv->widget->requisition.width; - height = priv->default_height + GTK_WIDGET (dialog)->requisition.height - priv->widget->requisition.height; + &default_width, &default_height); - gtk_window_set_default_size (GTK_WINDOW (dialog), width, height); - file_chooser_widget_update_hints (dialog, width); -} + /* Ideal target size plus any extra size */ + width = default_width + width + (2 * GTK_CONTAINER (dialog)->border_width); + height = default_height + height + (2 * GTK_CONTAINER (dialog)->border_width); -static void -file_chooser_widget_default_size_changed (GtkWidget *widget, - GtkFileChooserDialog *dialog) -{ if (GTK_WIDGET_REALIZED (dialog)) - file_chooser_widget_default_realized_size_changed (widget, dialog); + clamp_to_screen (GTK_WIDGET (dialog), &width, &height); + + if (resizable) + { + gtk_window_set_resizable (GTK_WINDOW (dialog), resizable); + gtk_window_resize (GTK_WINDOW (dialog), width, height); + } else - file_chooser_widget_default_unrealized_size_changed (widget, dialog); + { + gtk_widget_set_size_request (GTK_WIDGET (dialog), width, -1); + gtk_window_set_resizable (GTK_WINDOW (dialog), resizable); + } } static void @@ -490,6 +393,7 @@ gtk_file_chooser_dialog_map (GtkWidget *widget) if (!GTK_WIDGET_MAPPED (priv->widget)) gtk_widget_map (priv->widget); + file_chooser_widget_default_size_changed (priv->widget, dialog); _gtk_file_chooser_embed_initial_focus (GTK_FILE_CHOOSER_EMBED (priv->widget)); GTK_WIDGET_CLASS (gtk_file_chooser_dialog_parent_class)->map (widget); diff --git a/gtk/gtkfilechooserembed.c b/gtk/gtkfilechooserembed.c index a2eced08d5..5816dcaf36 100644 --- a/gtk/gtkfilechooserembed.c +++ b/gtk/gtkfilechooserembed.c @@ -28,9 +28,7 @@ static void gtk_file_chooser_embed_class_init (gpointer g_iface); static void delegate_get_default_size (GtkFileChooserEmbed *chooser_embed, gint *default_width, gint *default_height); -static void delegate_get_resizable_hints (GtkFileChooserEmbed *chooser_embed, - gboolean *resize_horizontally, - gboolean *resize_vertically); +static gboolean delegate_get_resizable (GtkFileChooserEmbed *chooser_embed); static gboolean delegate_should_respond (GtkFileChooserEmbed *chooser_embed); static void delegate_initial_focus (GtkFileChooserEmbed *chooser_embed); static void delegate_default_size_changed (GtkFileChooserEmbed *chooser_embed, @@ -57,7 +55,7 @@ void _gtk_file_chooser_embed_delegate_iface_init (GtkFileChooserEmbedIface *iface) { iface->get_default_size = delegate_get_default_size; - iface->get_resizable_hints = delegate_get_resizable_hints; + iface->get_resizable = delegate_get_resizable; iface->should_respond = delegate_should_respond; iface->initial_focus = delegate_initial_focus; } @@ -96,13 +94,11 @@ delegate_get_default_size (GtkFileChooserEmbed *chooser_embed, { _gtk_file_chooser_embed_get_default_size (get_delegate (chooser_embed), default_width, default_height); } - -static void -delegate_get_resizable_hints (GtkFileChooserEmbed *chooser_embed, - gboolean *resize_horizontally, - gboolean *resize_vertically) + +static gboolean +delegate_get_resizable (GtkFileChooserEmbed *chooser_embed) { - _gtk_file_chooser_embed_get_resizable_hints (get_delegate (chooser_embed), resize_horizontally, resize_vertically); + return _gtk_file_chooser_embed_get_resizable (get_delegate (chooser_embed)); } static gboolean @@ -208,14 +204,10 @@ _gtk_file_chooser_embed_initial_focus (GtkFileChooserEmbed *chooser_embed) GTK_FILE_CHOOSER_EMBED_GET_IFACE (chooser_embed)->initial_focus (chooser_embed); } -void -_gtk_file_chooser_embed_get_resizable_hints (GtkFileChooserEmbed *chooser_embed, - gboolean *resize_horizontally, - gboolean *resize_vertically) +gboolean +_gtk_file_chooser_embed_get_resizable (GtkFileChooserEmbed *chooser_embed) { - g_return_if_fail (GTK_IS_FILE_CHOOSER_EMBED (chooser_embed)); - g_return_if_fail (resize_horizontally != NULL); - g_return_if_fail (resize_vertically != NULL); + g_return_val_if_fail (GTK_IS_FILE_CHOOSER_EMBED (chooser_embed), FALSE); - GTK_FILE_CHOOSER_EMBED_GET_IFACE (chooser_embed)->get_resizable_hints (chooser_embed, resize_horizontally, resize_vertically); + return GTK_FILE_CHOOSER_EMBED_GET_IFACE (chooser_embed)->get_resizable (chooser_embed); } diff --git a/gtk/gtkfilechooserembed.h b/gtk/gtkfilechooserembed.h index 9477da0687..083bd45d71 100644 --- a/gtk/gtkfilechooserembed.h +++ b/gtk/gtkfilechooserembed.h @@ -43,9 +43,7 @@ struct _GtkFileChooserEmbedIface void (*get_default_size) (GtkFileChooserEmbed *chooser_embed, gint *default_width, gint *default_height); - void (*get_resizable_hints) (GtkFileChooserEmbed *chooser_embed, - gboolean *resize_horizontally, - gboolean *resize_vertically); + gboolean (*get_resizable) (GtkFileChooserEmbed *chooser_embed); gboolean (*should_respond) (GtkFileChooserEmbed *chooser_embed); @@ -61,10 +59,7 @@ GType _gtk_file_chooser_embed_get_type (void) G_GNUC_CONST; void _gtk_file_chooser_embed_get_default_size (GtkFileChooserEmbed *chooser_embed, gint *default_width, gint *default_height); -void _gtk_file_chooser_embed_get_resizable_hints (GtkFileChooserEmbed *chooser_embed, - gboolean *resize_horizontally, - gboolean *resize_vertically); - +gboolean _gtk_file_chooser_embed_get_resizable (GtkFileChooserEmbed *chooser_embed); gboolean _gtk_file_chooser_embed_should_respond (GtkFileChooserEmbed *chooser_embed); void _gtk_file_chooser_embed_initial_focus (GtkFileChooserEmbed *chooser_embed); diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h index 32d15360a7..7a1522bd8e 100644 --- a/gtk/gtkfilechooserprivate.h +++ b/gtk/gtkfilechooserprivate.h @@ -112,10 +112,6 @@ struct _GtkFileChooserDialogPrivate char *file_system; /* for use with GtkFileChooserEmbed */ - gint default_width; - gint default_height; - gboolean resize_horizontally; - gboolean resize_vertically; gboolean response_requested; }; @@ -289,6 +285,9 @@ struct _GtkFileChooserDefault GSource *shortcuts_drag_outside_idle; #endif + gint default_width; + gint default_height; + /* Flags */ guint local_only : 1; |