diff options
author | James M. Cape <jcape@ignore-your.tv> | 2004-11-30 21:06:48 +0000 |
---|---|---|
committer | James M. Cape <jcape@src.gnome.org> | 2004-11-30 21:06:48 +0000 |
commit | 1b45c64014d37e89fcaa2600cbda266f4d8cb5ca (patch) | |
tree | 1e35049232753fdf973b32ab91a9bfb1f681985d /gtk/gtkfilechooserbutton.c | |
parent | f79a113bedb8217c418afbf0c293098d46f492a7 (diff) | |
download | gtk+-1b45c64014d37e89fcaa2600cbda266f4d8cb5ca.tar.gz |
removed "GtkFileChooserButton:active" property and getter/setter.
2004-11-30 James M. Cape <jcape@ignore-your.tv>
* gtk/gtkfilechooserbutton.h (gtk_file_chooser_button_get_active)
(gtk_file_chooser_button_set_active):
* gtk/gtkfilechooserbutton.c (gtk_file_chooser_button_class_init)
(gtk_file_chooser_button_get_active)
(gtk_file_chooser_button_set_active):
* docs/reference/gtk/gtk-sections.txt:
* docs/reference/gtk/tmpl/gtkfilechooserbutton.sgml:
* gtk/gtk.symbols: removed "GtkFileChooserButton:active" property and
getter/setter.
* gtk/gtkfilechooserbutton.c (struct _GtkFileChooserButtonPrivate)
(button_toggled_cb) (dialog_response_cb) (button_notify_active_cb)
(gtk_file_chooser_button_init) (button_clicked_cb)
(gtk_file_chooser_button_show): Use a GtkButton instead of a
GtkToggleButton.
(struct _GtkFileChooserButtonPrivate)
(gtk_file_chooser_button_destroy) (gtk_file_chooser_button_style_set)
(gtk_file_chooser_button_screen_changed): Don't bother with the
(remove_settings_signal) (settings_notify_cb) (check_icon_theme):
Don't use GtkSettings at all, just call change_icon_theme() directly.
(struct _GtkFileChooserButtonPrivate)
(gtk_file_chooser_button_init)
(gtk_file_chooser_button_drag_data_received)
(gtk_file_chooser_button_mnemonic_activate)
(gtk_file_chooser_button_set_width_chars)
(gtk_file_chooser_button_get_width_chars)
(entry_changed_cb) (update_idler) (update_entry) (update_dialog)
(dialog_selection_changed_cb) (dialog_response_cb)
(entry_size_allocate_cb): Remove all references to the now-defunct
entry, store the old path (to support "Cancel") in an instance member.
(update_label_and_image) (update_label) (update_image)
(gtk_file_chooser_button_init) (dialog_response_cb)
(dialog_selection_changed_cb): Merge label/image updates, only display
the filename (not the whole path, fixes #157725).
(struct _GtkFileChooserButtonPrivate)
(dialog_selection_changed_cb)
(dialog_selection_changed_proxy_cb): Merge "selection-changed"
handlers, block while dialog is visible (fixes #158482).
* tests/testfilechooserbutton.c (delete_event_cb)
(properties_button_clicked_cb) (print_selected_path_clicked_cb)
(tests_button_clicked_cb) (main): Add per-chooser "tests" window,
don't delete on WM close, update properties_button_clicked_cb()
"delete-event" callback.
Diffstat (limited to 'gtk/gtkfilechooserbutton.c')
-rw-r--r-- | gtk/gtkfilechooserbutton.c | 878 |
1 files changed, 144 insertions, 734 deletions
diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c index 014d53f6fe..98ba56ef87 100644 --- a/gtk/gtkfilechooserbutton.c +++ b/gtk/gtkfilechooserbutton.c @@ -32,18 +32,15 @@ #include "gtkalias.h" #include "gtkintl.h" +#include "gtkbutton.h" #include "gtkdnd.h" -#include "gtkentry.h" -#include "gtkhbox.h" #include "gtkicontheme.h" #include "gtkiconfactory.h" #include "gtkimage.h" #include "gtklabel.h" #include "gtkstock.h" -#include "gtktogglebutton.h" #include "gtkvseparator.h" #include "gtkfilechooserdialog.h" -#include "gtkfilechooserentry.h" #include "gtkfilechooserprivate.h" #include "gtkfilechooserutils.h" @@ -61,8 +58,6 @@ #define ENTRY_BUTTON_SPACING 0 #define FALLBACK_ICON_SIZE 20 #define FALLBACK_ICON_NAME "stock_unknown" -#define NEW_FILE_ICON_NAME "stock_new" -#define NEW_DIR_ICON_NAME "stock_new-dir" /* ********************** * * Private Enumerations * @@ -75,7 +70,6 @@ enum PROP_DIALOG, PROP_TITLE, - PROP_ACTIVE, PROP_WIDTH_CHARS }; @@ -87,24 +81,19 @@ enum struct _GtkFileChooserButtonPrivate { GtkWidget *dialog; - GtkWidget *accept_button; - GtkWidget *entry_box; - GtkWidget *entry_image; - GtkWidget *entry; - GtkWidget *label_box; - GtkWidget *label_image; - GtkWidget *label; GtkWidget *button; + GtkWidget *image; + GtkWidget *label; + GtkFilePath *old_path; gchar *backend; - gulong entry_changed_id; gulong dialog_file_activated_id; gulong dialog_folder_changed_id; gulong dialog_selection_changed_id; - gulong dialog_selection_changed_proxy_id; - gulong settings_signal_id; - guint update_id; gint icon_size; + + /* Used for hiding/showing the dialog when the button is hidden */ + guint8 active : 1; }; @@ -162,8 +151,6 @@ static void dialog_update_preview_cb (GtkFileChooser *di gpointer user_data); static void dialog_selection_changed_cb (GtkFileChooser *dialog, gpointer user_data); -static void dialog_selection_changed_proxy_cb (GtkFileChooser *dialog, - gpointer user_data); static void dialog_file_activated_cb (GtkFileChooser *dialog, gpointer user_data); static void dialog_current_folder_changed_cb (GtkFileChooser *dialog, @@ -174,30 +161,15 @@ static void dialog_notify_cb (GObject *di static gboolean dialog_delete_event_cb (GtkWidget *dialog, GdkEvent *event, gpointer user_data); -static void dialog_response_cb (GtkFileChooser *dialog, +static void dialog_response_cb (GtkDialog *dialog, gint response, gpointer user_data); -static void button_toggled_cb (GtkToggleButton *real_button, - gpointer user_data); -static void button_notify_active_cb (GObject *real_button, - GParamSpec *pspec, - gpointer user_data); - -static void entry_size_allocate_cb (GtkWidget *entry, - GtkAllocation *allocation, - gpointer user_data); -static void entry_changed_cb (GtkEditable *editable, +static void button_clicked_cb (GtkButton *real_button, gpointer user_data); /* Utility Functions */ -static void remove_settings_signal (GtkFileChooserButton *button, - GdkScreen *screen); - -static void update_dialog (GtkFileChooserButton *button); -static void update_entry (GtkFileChooserButton *button); -static void update_label (GtkFileChooserButton *button); -static void update_icons (GtkFileChooserButton *button); +static void update_label_and_image (GtkFileChooserButton *button); /* ******************* * @@ -269,21 +241,6 @@ gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class) G_PARAM_READWRITE)); /** - * GtkFileChooserButton:active: - * - * %TRUE, if the #GtkFileChooserDialog associated with the button has been - * made visible. This can also be set by the application, though it is - * rarely useful to do so. - * - * Since: 2.6 - */ - g_object_class_install_property (gobject_class, PROP_ACTIVE, - g_param_spec_boolean ("active", - P_("Active"), - P_("Whether the browse dialog is visible or not."), - FALSE, G_PARAM_READWRITE)); - - /** * GtkFileChooserButton:width-chars: * * The width of the entry and label inside the button, in characters. @@ -310,8 +267,6 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button) GtkWidget *box, *image, *sep; GtkTargetList *target_list; - gtk_box_set_spacing (GTK_BOX (button), ENTRY_BUTTON_SPACING); - priv = G_TYPE_INSTANCE_GET_PRIVATE (button, GTK_TYPE_FILE_CHOOSER_BUTTON, GtkFileChooserButtonPrivate); button->priv = priv; @@ -320,60 +275,38 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button) gtk_widget_push_composite_child (); - priv->entry_box = gtk_hbox_new (FALSE, 4); - gtk_container_add (GTK_CONTAINER (button), priv->entry_box); - - priv->entry_image = gtk_image_new (); - gtk_box_pack_start (GTK_BOX (priv->entry_box), priv->entry_image, - FALSE, FALSE, 0); - gtk_widget_show (priv->entry_image); - - priv->entry = _gtk_file_chooser_entry_new (FALSE); - gtk_container_add (GTK_CONTAINER (priv->entry_box), priv->entry); - gtk_widget_show (priv->entry); - - priv->button = gtk_toggle_button_new (); - g_signal_connect (priv->button, "toggled", - G_CALLBACK (button_toggled_cb), button); - g_signal_connect (priv->button, "notify::active", - G_CALLBACK (button_notify_active_cb), button); - g_signal_connect (priv->entry, "size-allocate", - G_CALLBACK (entry_size_allocate_cb), priv->button); - gtk_box_pack_start (GTK_BOX (button), priv->button, TRUE, TRUE, 0); + priv->button = gtk_button_new (); + g_signal_connect (priv->button, "clicked", G_CALLBACK (button_clicked_cb), + button); + gtk_container_add (GTK_CONTAINER (button), priv->button); gtk_widget_show (priv->button); box = gtk_hbox_new (FALSE, 4); gtk_container_add (GTK_CONTAINER (priv->button), box); gtk_widget_show (box); - - priv->label_box = gtk_hbox_new (FALSE, 6); - gtk_container_add (GTK_CONTAINER (box), priv->label_box); - gtk_widget_show (priv->label_box); - priv->label_image = gtk_image_new (); - gtk_box_pack_start (GTK_BOX (priv->label_box), priv->label_image, - FALSE, FALSE, 0); - gtk_widget_show (priv->label_image); + priv->image = gtk_image_new (); + gtk_box_pack_start (GTK_BOX (box), priv->image, FALSE, FALSE, 0); + gtk_widget_show (priv->image); priv->label = gtk_label_new (_(DEFAULT_FILENAME)); gtk_label_set_ellipsize (GTK_LABEL (priv->label), PANGO_ELLIPSIZE_START); gtk_misc_set_alignment (GTK_MISC (priv->label), 0.0, 0.5); - gtk_container_add (GTK_CONTAINER (priv->label_box), priv->label); + gtk_container_add (GTK_CONTAINER (box), priv->label); gtk_widget_show (priv->label); sep = gtk_vseparator_new (); - gtk_box_pack_end (GTK_BOX (priv->label_box), sep, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (box), sep, FALSE, FALSE, 0); gtk_widget_show (sep); image = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_SMALL_TOOLBAR); - gtk_box_pack_end (GTK_BOX (box), image, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0); gtk_widget_show (image); gtk_widget_pop_composite_child (); /* DnD */ - gtk_drag_dest_unset (priv->entry); gtk_drag_dest_set (GTK_WIDGET (button), (GTK_DEST_DEFAULT_ALL), NULL, 0, @@ -397,7 +330,6 @@ gtk_file_chooser_button_constructor (GType type, { GObject *object; GtkFileChooserButtonPrivate *priv; - GtkFilePath *path; object = (*G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->constructor) (type, n_params, @@ -409,20 +341,23 @@ gtk_file_chooser_button_constructor (GType type, if (priv->backend) priv->dialog = gtk_file_chooser_dialog_new_with_backend (NULL, NULL, GTK_FILE_CHOOSER_ACTION_OPEN, - priv->backend, NULL); + priv->backend, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, + GTK_RESPONSE_ACCEPT, + NULL); else priv->dialog = gtk_file_chooser_dialog_new (NULL, NULL, GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, + GTK_RESPONSE_ACCEPT, NULL); - gtk_dialog_add_button (GTK_DIALOG (priv->dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - priv->accept_button = gtk_dialog_add_button (GTK_DIALOG (priv->dialog), - GTK_STOCK_OPEN, - GTK_RESPONSE_ACCEPT); gtk_dialog_set_default_response (GTK_DIALOG (priv->dialog), GTK_RESPONSE_ACCEPT); - gtk_dialog_set_alternative_button_order (GTK_DIALOG (priv->dialog), GTK_RESPONSE_ACCEPT, GTK_RESPONSE_CANCEL, @@ -449,9 +384,6 @@ gtk_file_chooser_button_constructor (GType type, priv->dialog_selection_changed_id = g_signal_connect (priv->dialog, "selection-changed", G_CALLBACK (dialog_selection_changed_cb), object); - priv->dialog_selection_changed_proxy_id = - g_signal_connect (priv->dialog, "selection-changed", - G_CALLBACK (dialog_selection_changed_proxy_cb), object); g_signal_connect (priv->dialog, "update-preview", G_CALLBACK (dialog_update_preview_cb), object); g_signal_connect (priv->dialog, "notify", @@ -459,17 +391,6 @@ gtk_file_chooser_button_constructor (GType type, g_object_add_weak_pointer (G_OBJECT (priv->dialog), (gpointer *) (&priv->dialog)); - _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (priv->entry), - _gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog))); - path = gtk_file_path_new_steal ("/"); - _gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (priv->entry), - path); - priv->entry_changed_id = g_signal_connect (priv->entry, "changed", - G_CALLBACK (entry_changed_cb), - object); - - update_label (GTK_FILE_CHOOSER_BUTTON (object)); - return object; } @@ -489,10 +410,6 @@ gtk_file_chooser_button_set_property (GObject *object, /* Construct-only */ priv->dialog = g_value_get_object (value); break; - case PROP_ACTIVE: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), - g_value_get_boolean (value)); - break; case PROP_WIDTH_CHARS: gtk_file_chooser_button_set_width_chars (GTK_FILE_CHOOSER_BUTTON (object), g_value_get_int (value)); @@ -509,45 +426,16 @@ gtk_file_chooser_button_set_property (GObject *object, eclass = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION); eval = g_enum_get_value (eclass, g_value_get_enum (value)); - g_warning ("%s: Choosers of type `%s` do not support `%s'.", + g_warning ("%s: Choosers of type `%s' do not support `%s'.", G_STRFUNC, G_OBJECT_TYPE_NAME (object), eval->value_name); g_value_set_enum ((GValue *) value, GTK_FILE_CHOOSER_ACTION_OPEN); } break; } - - g_object_set_property (G_OBJECT (priv->dialog), pspec->name, value); - _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (priv->entry), - g_value_get_enum (value)); - update_icons (GTK_FILE_CHOOSER_BUTTON (object)); - switch (g_value_get_enum (value)) - { - case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: - gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog)); - /* Fall through to set the widget states */ - case GTK_FILE_CHOOSER_ACTION_OPEN: - gtk_widget_hide (priv->entry_box); - gtk_widget_show (priv->label_box); - gtk_box_set_child_packing (GTK_BOX (object), priv->button, - TRUE, TRUE, 0, GTK_PACK_START); - gtk_button_set_label (GTK_BUTTON (priv->accept_button), - GTK_STOCK_OPEN); - break; - - case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: - gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog)); - /* Fall through to set the widget states */ - case GTK_FILE_CHOOSER_ACTION_SAVE: - gtk_widget_show (priv->entry_box); - gtk_widget_hide (priv->label_box); - gtk_box_set_child_packing (GTK_BOX (object), priv->button, - FALSE, FALSE, 0, GTK_PACK_START); - gtk_button_set_label (GTK_BUTTON (priv->accept_button), - GTK_STOCK_SAVE); - break; - } + g_object_set_property (G_OBJECT (priv->dialog), pspec->name, value); + update_label_and_image (GTK_FILE_CHOOSER_BUTTON (object)); break; case PROP_TITLE: @@ -588,13 +476,9 @@ gtk_file_chooser_button_get_property (GObject *object, switch (param_id) { - case PROP_ACTIVE: - g_value_set_boolean (value, - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->button))); - break; case PROP_WIDTH_CHARS: g_value_set_int (value, - gtk_entry_get_width_chars (GTK_ENTRY (priv->entry))); + gtk_label_get_width_chars (GTK_LABEL (priv->label))); break; case PROP_TITLE: @@ -629,14 +513,11 @@ gtk_file_chooser_button_destroy (GtkObject * object) priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (object); - if (priv->update_id) - g_source_remove (priv->update_id); - if (priv->dialog != NULL) gtk_widget_destroy (priv->dialog); - - remove_settings_signal (GTK_FILE_CHOOSER_BUTTON (object), - gtk_widget_get_screen (GTK_WIDGET (object))); + + if (priv->old_path) + gtk_file_path_free (priv->old_path); if (GTK_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->destroy != NULL) (*GTK_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->destroy) (object); @@ -657,6 +538,8 @@ gtk_file_chooser_button_drag_data_received (GtkWidget *widget, guint drag_time) { GtkFileChooserButtonPrivate *priv; + GtkFileSystem *fs; + GtkFilePath *path; gchar *text; if (GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->drag_data_received != NULL) @@ -671,11 +554,14 @@ gtk_file_chooser_button_drag_data_received (GtkWidget *widget, priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (widget); + fs = _gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog)); + switch (info) { case TEXT_URI_LIST: { gchar **uris; + GtkFilePath *base_path; guint i; gboolean selected; @@ -687,10 +573,6 @@ gtk_file_chooser_button_drag_data_received (GtkWidget *widget, selected = FALSE; for (i = 0; !selected && uris[i] != NULL; i++) { - GtkFileSystem *fs; - GtkFilePath *path, *base_path; - - fs = _gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog)); path = gtk_file_system_uri_to_path (fs, uris[i]); base_path = NULL; @@ -713,11 +595,9 @@ gtk_file_chooser_button_drag_data_received (GtkWidget *widget, g_object_get (priv->dialog, "action", &action, NULL); selected = - ((((action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER || - action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) && + (((action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER && gtk_file_info_get_is_folder (info)) || - ((action == GTK_FILE_CHOOSER_ACTION_OPEN || - action == GTK_FILE_CHOOSER_ACTION_SAVE) && + (action == GTK_FILE_CHOOSER_ACTION_OPEN && !gtk_file_info_get_is_folder (info))) && _gtk_file_chooser_select_path (GTK_FILE_CHOOSER (priv->dialog), path, NULL)); @@ -739,8 +619,13 @@ gtk_file_chooser_button_drag_data_received (GtkWidget *widget, case TEXT_PLAIN: text = gtk_selection_data_get_text (data); - gtk_entry_set_text (GTK_ENTRY (priv->entry), text); - g_free (text); + path = gtk_file_path_new_steal (text); + _gtk_file_chooser_select_path (GTK_FILE_CHOOSER (priv->dialog), path, + NULL); + gtk_file_path_free (path); + break; + + default: break; } @@ -769,7 +654,7 @@ gtk_file_chooser_button_show (GtkWidget *widget) if (GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->show) (*GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->show) (widget); - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->button))) + if (priv->active) gtk_widget_show (priv->dialog); } @@ -793,18 +678,7 @@ gtk_file_chooser_button_mnemonic_activate (GtkWidget *widget, GtkFileChooserButtonPrivate *priv; priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (widget); - - switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (priv->dialog))) - { - case GTK_FILE_CHOOSER_ACTION_OPEN: - case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: - gtk_widget_grab_focus (priv->button); - break; - case GTK_FILE_CHOOSER_ACTION_SAVE: - case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: - gtk_widget_grab_focus (priv->entry); - break; - } + gtk_widget_grab_focus (priv->button); return TRUE; } @@ -824,44 +698,7 @@ change_icon_theme (GtkFileChooserButton *button) else button->priv->icon_size = FALLBACK_ICON_SIZE; - update_icons (button); -} - -/* Callback used when a GtkSettings value changes */ -static void -settings_notify_cb (GObject *object, - GParamSpec *pspec, - gpointer user_data) -{ - const char *name; - - name = g_param_spec_get_name (pspec); - - if (strcmp (name, "gtk-icon-theme-name") == 0 - || strcmp (name, "gtk-icon-sizes") == 0) - change_icon_theme (user_data); -} - -/* Installs a signal handler for GtkSettings so that we can monitor changes in - * the icon theme. - */ -static void -check_icon_theme (GtkFileChooserButton *button) -{ - GtkSettings *settings; - - if (button->priv->settings_signal_id) - return; - - if (gtk_widget_has_screen (GTK_WIDGET (button))) - { - settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (button))); - button->priv->settings_signal_id = g_signal_connect (settings, "notify", - G_CALLBACK (settings_notify_cb), - button); - - change_icon_theme (button); - } + update_label_and_image (button); } static void @@ -888,8 +725,7 @@ gtk_file_chooser_button_screen_changed (GtkWidget *widget, (*GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->screen_changed) (widget, old_screen); - remove_settings_signal (button, old_screen); - check_icon_theme (button); + change_icon_theme (button); } @@ -997,42 +833,6 @@ gtk_file_chooser_button_get_title (GtkFileChooserButton *button) } /** - * gtk_file_chooser_button_set_active: - * @button: the button widget to modify. - * @is_active: whether or not the dialog is visible. - * - * Modifies whether or not the dialog attached to @button is visible or not. - * - * Since: 2.6 - **/ -void -gtk_file_chooser_button_set_active (GtkFileChooserButton *button, - gboolean is_active) -{ - g_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button)); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->priv->button), is_active); -} - -/** - * gtk_file_chooser_button_get_active: - * @button: the button widget to examine. - * - * Retrieves whether or not the dialog attached to @button is visible. - * - * Returns: a boolean whether the dialog is visible or not. - * - * Since: 2.6 - **/ -gboolean -gtk_file_chooser_button_get_active (GtkFileChooserButton *button) -{ - g_return_val_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button), FALSE); - - return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button->priv->button)); -} - -/** * gtk_file_chooser_button_get_width_chars: * @button: the button widget to examine. * @@ -1047,7 +847,7 @@ gtk_file_chooser_button_get_width_chars (GtkFileChooserButton *button) { g_return_val_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button), -1); - return gtk_entry_get_width_chars (GTK_ENTRY (button->priv->entry)); + return gtk_label_get_width_chars (GTK_LABEL (button->priv->label)); } /** @@ -1065,7 +865,6 @@ gtk_file_chooser_button_set_width_chars (GtkFileChooserButton *button, { g_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button)); - gtk_entry_set_width_chars (GTK_ENTRY (button->priv->entry), n_chars); gtk_label_set_width_chars (GTK_LABEL (button->priv->label), n_chars); g_object_notify (G_OBJECT (button), "width-chars"); } @@ -1075,23 +874,7 @@ gtk_file_chooser_button_set_width_chars (GtkFileChooserButton *button, * Utility Functions * * ******************* */ -/* Removes the settings signal handler. It's safe to call multiple times */ -static void -remove_settings_signal (GtkFileChooserButton *button, - GdkScreen *screen) -{ - if (button->priv->settings_signal_id) - { - GtkSettings *settings; - - settings = gtk_settings_get_for_screen (screen); - g_signal_handler_disconnect (settings, - button->priv->settings_signal_id); - button->priv->settings_signal_id = 0; - } -} - -static GtkIconTheme * +static inline GtkIconTheme * get_icon_theme (GtkWidget *widget) { if (gtk_widget_has_screen (widget)) @@ -1100,146 +883,25 @@ get_icon_theme (GtkWidget *widget) return gtk_icon_theme_get_default (); } -static gboolean -check_if_path_exists (GtkFileSystem *fs, - const GtkFilePath *path) -{ - gboolean path_exists; - GtkFilePath *parent_path; - - path_exists = FALSE; - parent_path = NULL; - - if (gtk_file_system_get_parent (fs, path, &parent_path, NULL)) - { - GtkFileFolder *folder; - - folder = gtk_file_system_get_folder (fs, parent_path, 0, NULL); - if (folder) - { - GtkFileInfo *info; - - info = gtk_file_folder_get_info (folder, path, NULL); - if (info) - { - path_exists = TRUE; - gtk_file_info_free (info); - } - - g_object_unref (folder); - } - - gtk_file_path_free (parent_path); - } - - return path_exists; -} - static void -update_icons (GtkFileChooserButton *button) +update_label_and_image (GtkFileChooserButton *button) { GtkFileChooserButtonPrivate *priv; GdkPixbuf *pixbuf; - GSList *paths; - - priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (button); - pixbuf = NULL; - paths = _gtk_file_chooser_get_paths (GTK_FILE_CHOOSER (priv->dialog)); - - if (paths) - { - GtkFilePath *path; - GtkFileSystem *fs; - - path = paths->data; - fs = _gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog)); - - switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (priv->dialog))) - { - case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: - { - GtkFileSystemVolume *volume; - - volume = gtk_file_system_get_volume_for_path (fs, path); - if (volume) - { - GtkFilePath *base_path; - - base_path = gtk_file_system_volume_get_base_path (fs, volume); - - if (base_path && gtk_file_path_compare (base_path, path) == 0) - pixbuf = gtk_file_system_volume_render_icon (fs, volume, - GTK_WIDGET (button), - priv->icon_size, - NULL); - - if (base_path) - gtk_file_path_free (base_path); - - gtk_file_system_volume_free (fs, volume); - } - } - - case GTK_FILE_CHOOSER_ACTION_OPEN: - if (!pixbuf) - pixbuf = gtk_file_system_render_icon (fs, path, GTK_WIDGET (button), - priv->icon_size, NULL); - break; - - case GTK_FILE_CHOOSER_ACTION_SAVE: - if (check_if_path_exists (fs, path)) - pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)), - GTK_STOCK_DIALOG_WARNING, - priv->icon_size, 0, NULL); - else - pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)), - NEW_FILE_ICON_NAME, - priv->icon_size, 0, NULL); - break; - case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: - if (check_if_path_exists (fs, path)) - pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)), - GTK_STOCK_DIALOG_WARNING, - priv->icon_size, 0, NULL); - else - pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)), - NEW_DIR_ICON_NAME, - priv->icon_size, 0, NULL); - break; - } - - gtk_file_paths_free (paths); - } - - if (!pixbuf) - pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)), - FALLBACK_ICON_NAME, - priv->icon_size, 0, NULL); - - gtk_image_set_from_pixbuf (GTK_IMAGE (priv->entry_image), pixbuf); - gtk_image_set_from_pixbuf (GTK_IMAGE (priv->label_image), pixbuf); - - if (pixbuf) - g_object_unref (pixbuf); -} - - -static void -update_label (GtkFileChooserButton *button) -{ - GtkFileChooserButtonPrivate *priv; gchar *label_text; GSList *paths; priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (button); paths = _gtk_file_chooser_get_paths (GTK_FILE_CHOOSER (button->priv->dialog)); label_text = NULL; + pixbuf = NULL; if (paths) { GtkFileSystem *fs; - GtkFilePath *path; + GtkFilePath *path, *parent_path; GtkFileSystemVolume *volume; + GtkFileFolder *folder; path = paths->data; @@ -1252,7 +914,13 @@ update_label (GtkFileChooserButton *button) base_path = gtk_file_system_volume_get_base_path (fs, volume); if (base_path && gtk_file_path_compare (base_path, path) == 0) - label_text = gtk_file_system_volume_get_display_name (fs, volume); + { + label_text = gtk_file_system_volume_get_display_name (fs, volume); + pixbuf = gtk_file_system_volume_render_icon (fs, volume, + GTK_WIDGET (button), + priv->icon_size, + NULL); + } if (base_path) gtk_file_path_free (base_path); @@ -1262,60 +930,28 @@ update_label (GtkFileChooserButton *button) if (label_text) goto out; } - - if (gtk_file_system_path_is_local (fs, path)) - { - const gchar *home; - gchar *tmp; - gchar *filename; - - filename = gtk_file_system_path_to_filename (fs, path); - - if (!filename) - goto out; - - home = g_get_home_dir (); - - /* Munging for psuedo-volumes and files in the user's home tree */ - if (home) - { - if (strcmp (filename, home) == 0) - { - label_text = g_strdup (_("Home")); - goto localout; - } - - tmp = g_build_filename (home, "Desktop", NULL); - - if (strcmp (filename, tmp) == 0) - label_text = g_strdup (_("Desktop")); - g_free (tmp); + if (!pixbuf) + pixbuf = gtk_file_system_render_icon (fs, path, GTK_WIDGET (button), + priv->icon_size, NULL); - if (label_text) - goto out; + parent_path = NULL; + gtk_file_system_get_parent (fs, path, &parent_path, NULL); - if (g_str_has_prefix (filename, home)) - { - label_text = g_strconcat ("~", filename + strlen (home), NULL); - goto localout; - } - } - - if (!label_text) - label_text = g_strdup (filename); - - localout: - g_free (filename); - } - else + folder = gtk_file_system_get_folder (fs, parent_path ? parent_path : path, + GTK_FILE_INFO_DISPLAY_NAME, NULL); + if (folder) { - gchar *uri; + GtkFileInfo *info; - uri = gtk_file_system_path_to_uri (fs, path); + info = gtk_file_folder_get_info (folder, path, NULL); + g_object_unref (folder); - if (uri) - label_text = uri; + if (info) + { + label_text = g_strdup (gtk_file_info_get_display_name (info)); + gtk_file_info_free (info); + } } out: @@ -1329,180 +965,15 @@ update_label (GtkFileChooserButton *button) } else gtk_label_set_text (GTK_LABEL (priv->label), _(DEFAULT_FILENAME)); -} - -static void -update_entry (GtkFileChooserButton *button) -{ - GtkFileChooserButtonPrivate *priv; - GSList *paths; - gchar *filename; - - priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (button); - - paths = _gtk_file_chooser_get_paths (GTK_FILE_CHOOSER (priv->dialog)); - - if (paths) - { - GtkFileSystem *fs; - GtkFilePath *path; - - path = paths->data; - fs = _gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog)); - - if (gtk_file_system_path_is_local (fs, path)) - { - filename = gtk_file_system_path_to_filename (fs, path); - - if (filename) - { - const gchar *home; - gchar *tmp; - - if (g_file_test (filename, G_FILE_TEST_IS_DIR)) - { - tmp = g_strconcat (filename, "/", NULL); - g_free (filename); - filename = tmp; - } - - home = g_get_home_dir (); - - if (home && g_str_has_prefix (filename, home)) - { - tmp = g_strconcat ("~", filename + strlen (home), NULL); - g_free (filename); - filename = tmp; - } - } - } - else - filename = gtk_file_system_path_to_uri (fs, path); - } - else - filename = NULL; - - if (filename) - { - gchar *entry_text; - - entry_text = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL); - g_free (filename); - - gtk_entry_set_text (GTK_ENTRY (priv->entry), entry_text); - g_free (entry_text); - } - else - gtk_entry_set_text (GTK_ENTRY (priv->entry), ""); -} - -static void -update_dialog (GtkFileChooserButton *button) -{ - GtkFileChooserButtonPrivate *priv; - GtkFilePath *current_folder; - GtkFileSystem *fs; - GtkFilePath *folder_part, *full_path; - gchar *file_part; - const gchar *text; - GtkFilePath *base_path; - - priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (button); - file_part = NULL; - folder_part = NULL; - fs = _gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog)); - - text = gtk_entry_get_text (GTK_ENTRY (priv->entry)); - - base_path = gtk_file_path_new_dup ("/"); - gtk_file_system_parse (fs, base_path, text, &folder_part, &file_part, NULL); - gtk_file_path_free (base_path); - - switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (priv->dialog))) - { - case GTK_FILE_CHOOSER_ACTION_OPEN: - gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog)); - if (folder_part) - { - GtkFileFolder *folder; - GtkFileInfo *info; - - folder = gtk_file_system_get_folder (fs, folder_part, - GTK_FILE_INFO_IS_FOLDER, NULL); - - full_path = gtk_file_system_make_path (fs, folder_part, file_part, NULL); - info = gtk_file_folder_get_info (folder, full_path, NULL); - - /* Entry contents don't exist. */ - if (info == NULL) - _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (priv->dialog), - folder_part, NULL); - /* Entry contents are a folder */ - else if (gtk_file_info_get_is_folder (info)) - _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (priv->dialog), - full_path, NULL); - /* Entry contents must be a file. */ - else - _gtk_file_chooser_select_path (GTK_FILE_CHOOSER (priv->dialog), - full_path, NULL); - - if (info) - gtk_file_info_free (info); - - gtk_file_path_free (full_path); - } - break; - case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: - gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog)); - if (folder_part) - { - /* Entry contents don't exist. */ - if (file_part && file_part[0] != '\0') - { - full_path = gtk_file_system_make_path (fs, folder_part, file_part, - NULL); - if (full_path) - { - _gtk_file_chooser_select_path (GTK_FILE_CHOOSER (priv->dialog), - full_path, NULL); - gtk_file_path_free (full_path); - } - else - _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (priv->dialog), - folder_part, NULL); - } - else - { - _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (priv->dialog), - folder_part, NULL); - } - } - break; - - case GTK_FILE_CHOOSER_ACTION_SAVE: - case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: - gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog)); - if (folder_part) - { - current_folder = _gtk_file_chooser_get_current_folder_path (GTK_FILE_CHOOSER (priv->dialog)); - - if (!current_folder || - gtk_file_path_compare (current_folder, folder_part) != 0) - { - _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (priv->dialog), - folder_part, NULL); - g_signal_emit_by_name (button, "current-folder-changed"); - } - - if (current_folder) - gtk_file_path_free (current_folder); - } + + if (!pixbuf) + pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)), + FALLBACK_ICON_NAME, + priv->icon_size, 0, NULL); - gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (priv->dialog), - file_part); - g_signal_emit_by_name (button, "selection-changed"); - break; - } + gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf); + if (pixbuf) + g_object_unref (pixbuf); } /* ************************ * @@ -1527,25 +998,7 @@ static void dialog_selection_changed_cb (GtkFileChooser *dialog, gpointer user_data) { - GtkFileChooserButtonPrivate *priv; - - priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (user_data); - - g_signal_handler_block (priv->entry, priv->entry_changed_id); - update_entry (user_data); - g_signal_handler_unblock (priv->entry, priv->entry_changed_id); - update_icons (user_data); - update_label (user_data); -} - -static void -dialog_selection_changed_proxy_cb (GtkFileChooser *dialog, - gpointer user_data) -{ - GtkFileChooserButtonPrivate *priv; - - priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (user_data); - + update_label_and_image (user_data); g_signal_emit_by_name (user_data, "selection-changed"); } @@ -1580,9 +1033,9 @@ dialog_delete_event_cb (GtkWidget *dialog, } static void -dialog_response_cb (GtkFileChooser *dialog, - gint response, - gpointer user_data) +dialog_response_cb (GtkDialog *dialog, + gint response, + gpointer user_data) { GtkFileChooserButtonPrivate *priv; @@ -1590,36 +1043,58 @@ dialog_response_cb (GtkFileChooser *dialog, if (response == GTK_RESPONSE_ACCEPT) { - g_signal_handler_block (priv->entry, priv->entry_changed_id); - update_entry (user_data); - g_signal_handler_unblock (priv->entry, priv->entry_changed_id); - update_label (user_data); - update_icons (user_data); - g_signal_emit_by_name (user_data, "current-folder-changed"); g_signal_emit_by_name (user_data, "selection-changed"); } - else + else if (priv->old_path) { - g_signal_handler_block (priv->dialog, priv->dialog_selection_changed_id); - update_dialog (user_data); - g_signal_handler_unblock (priv->dialog, priv->dialog_selection_changed_id); + switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog))) + { + case GTK_FILE_CHOOSER_ACTION_OPEN: + _gtk_file_chooser_select_path (GTK_FILE_CHOOSER (dialog), priv->old_path, + NULL); + break; + case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: + _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (dialog), + priv->old_path, NULL); + break; + default: + g_assert_not_reached (); + break; + } } - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), FALSE); + if (priv->old_path) + { + gtk_file_path_free (priv->old_path); + priv->old_path = NULL; + } + + update_label_and_image (user_data); + + g_signal_handler_unblock (priv->dialog, + priv->dialog_folder_changed_id); + g_signal_handler_unblock (priv->dialog, + priv->dialog_file_activated_id); + g_signal_handler_unblock (priv->dialog, + priv->dialog_selection_changed_id); + priv->active = FALSE; + gtk_widget_hide (priv->dialog); } static void -button_toggled_cb (GtkToggleButton *real_button, - gpointer user_data) +button_clicked_cb (GtkButton *real_button, + gpointer user_data) { GtkFileChooserButtonPrivate *priv; priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (user_data); - if (gtk_toggle_button_get_active (real_button)) + if (!priv->active) { + GSList *paths; + /* Setup the dialog parent to be chooser button's toplevel, and be modal as needed. */ if (!GTK_WIDGET_VISIBLE (priv->dialog)) @@ -1631,7 +1106,8 @@ button_toggled_cb (GtkToggleButton *real_button, if (GTK_WIDGET_TOPLEVEL (toplevel) && GTK_IS_WINDOW (toplevel)) { if (GTK_WINDOW (toplevel) != gtk_window_get_transient_for (GTK_WINDOW (priv->dialog))) - gtk_window_set_transient_for (GTK_WINDOW (priv->dialog), GTK_WINDOW (toplevel)); + gtk_window_set_transient_for (GTK_WINDOW (priv->dialog), + GTK_WINDOW (toplevel)); gtk_window_set_modal (GTK_WINDOW (priv->dialog), gtk_window_get_modal (GTK_WINDOW (toplevel))); @@ -1643,84 +1119,18 @@ button_toggled_cb (GtkToggleButton *real_button, g_signal_handler_block (priv->dialog, priv->dialog_file_activated_id); g_signal_handler_block (priv->dialog, - priv->dialog_selection_changed_proxy_id); - gtk_widget_set_sensitive (priv->entry, FALSE); - gtk_window_present (GTK_WINDOW (priv->dialog)); - } - else - { - g_signal_handler_unblock (priv->dialog, - priv->dialog_folder_changed_id); - g_signal_handler_unblock (priv->dialog, - priv->dialog_file_activated_id); - g_signal_handler_unblock (priv->dialog, - priv->dialog_selection_changed_proxy_id); - gtk_widget_set_sensitive (priv->entry, TRUE); - gtk_widget_hide (priv->dialog); - } -} - -static void -button_notify_active_cb (GObject *real_button, - GParamSpec *pspec, - gpointer user_data) -{ - g_object_notify (user_data, "active"); -} - - -static gboolean -update_idler (gpointer user_data) -{ - GtkFileChooserButtonPrivate *priv; - gboolean retval; - gint start, end; - - GDK_THREADS_ENTER (); - - priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (user_data); - - if (!gtk_editable_get_selection_bounds (GTK_EDITABLE (priv->entry), - &start, &end)) - { - g_signal_handler_block (priv->dialog, priv->dialog_selection_changed_id); - update_dialog (user_data); - g_signal_handler_unblock (priv->dialog, - priv->dialog_selection_changed_id); - update_icons (user_data); - update_label (user_data); - priv->update_id = 0; - retval = FALSE; - } - else - retval = FALSE; - - GDK_THREADS_LEAVE (); - - return retval; -} - -static void -entry_changed_cb (GtkEditable *editable, - gpointer user_data) -{ - GtkFileChooserButtonPrivate *priv; - - priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (user_data); + paths = _gtk_file_chooser_get_paths (GTK_FILE_CHOOSER (priv->dialog)); + if (paths) + { + if (paths->data) + priv->old_path = gtk_file_path_copy (paths->data); - if (priv->update_id) - g_source_remove (priv->update_id); + gtk_file_paths_free (paths); + } - priv->update_id = g_idle_add_full (G_PRIORITY_LOW, update_idler, - user_data, NULL); -} + priv->active = TRUE; + } -/* Ensure the button height == entry height */ -static void -entry_size_allocate_cb (GtkWidget *entry, - GtkAllocation *allocation, - gpointer user_data) -{ - gtk_widget_set_size_request (user_data, -1, allocation->height); + gtk_window_present (GTK_WINDOW (priv->dialog)); } |