Commit d64c7c08 authored by Federico Mena Quintero's avatar Federico Mena Quintero Committed by Federico Mena Quintero

New handler. Ask the GtkFileChooser widget if it wants to do something

2004-03-04  Federico Mena Quintero  <federico@ximian.com>

	* gtk/gtkfilechooserdialog.c (response_cb):  New handler.  Ask the
	GtkFileChooser widget if it wants to do something special rather
	than letting us terminate the dialog.
	(gtk_file_chooser_dialog_init): Connect to "response"; see the
	comment in the sources to see why we don't override the method in
	class_init.

	* gtk/gtkfilechooserembed.h (struct _GtkFileChooserEmbedIface):
	Added a ::should_respond() method.

	* gtk/gtkfilechooserembed.c
	(_gtk_file_chooser_embed_delegate_iface_init): Add a delegate for ::should_respond().
	(delegate_should_respond): New delegate.
	(_gtk_file_chooser_embed_should_respond): New function.

	* gtk/gtkfilechooserdefault.c (set_list_model, create_file_list):
	Use dashes in signal names rather than underscores.
	(gtk_file_chooser_default_init): Hook up our ::should_respond() implementation.
	(gtk_file_chooser_default_should_respond): Implement.  go into a
	folder rather than responding if we are in File mode and the
	selected file is a folder.
	(get_selection): New helper function.
	(add_bookmark_button_clicked_cb): Use get_selection().
	(bookmarks_check_add_sensitivity): Likewise.
	(gtk_file_chooser_default_get_paths): Likewise.
	(check_save_entry): New helper function.
	(gtk_file_chooser_default_get_paths): Use check_save_entry().
	(selection_check): Renamed from selection_is_folders().  Now
	checks whether the selection is empty, all files, all folders.
	(bookmarks_check_add_sensitivity): Use selection_check().
parent 1810dba3
2004-03-04 Federico Mena Quintero <federico@ximian.com>
* gtk/gtkfilechooserdialog.c (response_cb): New handler. Ask the
GtkFileChooser widget if it wants to do something special rather
than letting us terminate the dialog.
(gtk_file_chooser_dialog_init): Connect to "response"; see the
comment in the sources to see why we don't override the method in
class_init.
* gtk/gtkfilechooserembed.h (struct _GtkFileChooserEmbedIface):
Added a ::should_respond() method.
* gtk/gtkfilechooserembed.c
(_gtk_file_chooser_embed_delegate_iface_init): Add a delegate for ::should_respond().
(delegate_should_respond): New delegate.
(_gtk_file_chooser_embed_should_respond): New function.
* gtk/gtkfilechooserdefault.c (set_list_model, create_file_list):
Use dashes in signal names rather than underscores.
(gtk_file_chooser_default_init): Hook up our ::should_respond() implementation.
(gtk_file_chooser_default_should_respond): Implement. go into a
folder rather than responding if we are in File mode and the
selected file is a folder.
(get_selection): New helper function.
(add_bookmark_button_clicked_cb): Use get_selection().
(bookmarks_check_add_sensitivity): Likewise.
(gtk_file_chooser_default_get_paths): Likewise.
(check_save_entry): New helper function.
(gtk_file_chooser_default_get_paths): Use check_save_entry().
(selection_check): Renamed from selection_is_folders(). Now
checks whether the selection is empty, all files, all folders.
(bookmarks_check_add_sensitivity): Use selection_check().
Fri Mar 5 00:05:59 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtkcombobox.c (gtk_combo_box_list_setup):
......
2004-03-04 Federico Mena Quintero <federico@ximian.com>
* gtk/gtkfilechooserdialog.c (response_cb): New handler. Ask the
GtkFileChooser widget if it wants to do something special rather
than letting us terminate the dialog.
(gtk_file_chooser_dialog_init): Connect to "response"; see the
comment in the sources to see why we don't override the method in
class_init.
* gtk/gtkfilechooserembed.h (struct _GtkFileChooserEmbedIface):
Added a ::should_respond() method.
* gtk/gtkfilechooserembed.c
(_gtk_file_chooser_embed_delegate_iface_init): Add a delegate for ::should_respond().
(delegate_should_respond): New delegate.
(_gtk_file_chooser_embed_should_respond): New function.
* gtk/gtkfilechooserdefault.c (set_list_model, create_file_list):
Use dashes in signal names rather than underscores.
(gtk_file_chooser_default_init): Hook up our ::should_respond() implementation.
(gtk_file_chooser_default_should_respond): Implement. go into a
folder rather than responding if we are in File mode and the
selected file is a folder.
(get_selection): New helper function.
(add_bookmark_button_clicked_cb): Use get_selection().
(bookmarks_check_add_sensitivity): Likewise.
(gtk_file_chooser_default_get_paths): Likewise.
(check_save_entry): New helper function.
(gtk_file_chooser_default_get_paths): Use check_save_entry().
(selection_check): Renamed from selection_is_folders(). Now
checks whether the selection is empty, all files, all folders.
(bookmarks_check_add_sensitivity): Use selection_check().
Fri Mar 5 00:05:59 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtkcombobox.c (gtk_combo_box_list_setup):
......
2004-03-04 Federico Mena Quintero <federico@ximian.com>
* gtk/gtkfilechooserdialog.c (response_cb): New handler. Ask the
GtkFileChooser widget if it wants to do something special rather
than letting us terminate the dialog.
(gtk_file_chooser_dialog_init): Connect to "response"; see the
comment in the sources to see why we don't override the method in
class_init.
* gtk/gtkfilechooserembed.h (struct _GtkFileChooserEmbedIface):
Added a ::should_respond() method.
* gtk/gtkfilechooserembed.c
(_gtk_file_chooser_embed_delegate_iface_init): Add a delegate for ::should_respond().
(delegate_should_respond): New delegate.
(_gtk_file_chooser_embed_should_respond): New function.
* gtk/gtkfilechooserdefault.c (set_list_model, create_file_list):
Use dashes in signal names rather than underscores.
(gtk_file_chooser_default_init): Hook up our ::should_respond() implementation.
(gtk_file_chooser_default_should_respond): Implement. go into a
folder rather than responding if we are in File mode and the
selected file is a folder.
(get_selection): New helper function.
(add_bookmark_button_clicked_cb): Use get_selection().
(bookmarks_check_add_sensitivity): Likewise.
(gtk_file_chooser_default_get_paths): Likewise.
(check_save_entry): New helper function.
(gtk_file_chooser_default_get_paths): Use check_save_entry().
(selection_check): Renamed from selection_is_folders(). Now
checks whether the selection is empty, all files, all folders.
(bookmarks_check_add_sensitivity): Use selection_check().
Fri Mar 5 00:05:59 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtkcombobox.c (gtk_combo_box_list_setup):
......
2004-03-04 Federico Mena Quintero <federico@ximian.com>
* gtk/gtkfilechooserdialog.c (response_cb): New handler. Ask the
GtkFileChooser widget if it wants to do something special rather
than letting us terminate the dialog.
(gtk_file_chooser_dialog_init): Connect to "response"; see the
comment in the sources to see why we don't override the method in
class_init.
* gtk/gtkfilechooserembed.h (struct _GtkFileChooserEmbedIface):
Added a ::should_respond() method.
* gtk/gtkfilechooserembed.c
(_gtk_file_chooser_embed_delegate_iface_init): Add a delegate for ::should_respond().
(delegate_should_respond): New delegate.
(_gtk_file_chooser_embed_should_respond): New function.
* gtk/gtkfilechooserdefault.c (set_list_model, create_file_list):
Use dashes in signal names rather than underscores.
(gtk_file_chooser_default_init): Hook up our ::should_respond() implementation.
(gtk_file_chooser_default_should_respond): Implement. go into a
folder rather than responding if we are in File mode and the
selected file is a folder.
(get_selection): New helper function.
(add_bookmark_button_clicked_cb): Use get_selection().
(bookmarks_check_add_sensitivity): Likewise.
(gtk_file_chooser_default_get_paths): Likewise.
(check_save_entry): New helper function.
(gtk_file_chooser_default_get_paths): Use check_save_entry().
(selection_check): Renamed from selection_is_folders(). Now
checks whether the selection is empty, all files, all folders.
(bookmarks_check_add_sensitivity): Use selection_check().
Fri Mar 5 00:05:59 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtkcombobox.c (gtk_combo_box_list_setup):
......
2004-03-04 Federico Mena Quintero <federico@ximian.com>
* gtk/gtkfilechooserdialog.c (response_cb): New handler. Ask the
GtkFileChooser widget if it wants to do something special rather
than letting us terminate the dialog.
(gtk_file_chooser_dialog_init): Connect to "response"; see the
comment in the sources to see why we don't override the method in
class_init.
* gtk/gtkfilechooserembed.h (struct _GtkFileChooserEmbedIface):
Added a ::should_respond() method.
* gtk/gtkfilechooserembed.c
(_gtk_file_chooser_embed_delegate_iface_init): Add a delegate for ::should_respond().
(delegate_should_respond): New delegate.
(_gtk_file_chooser_embed_should_respond): New function.
* gtk/gtkfilechooserdefault.c (set_list_model, create_file_list):
Use dashes in signal names rather than underscores.
(gtk_file_chooser_default_init): Hook up our ::should_respond() implementation.
(gtk_file_chooser_default_should_respond): Implement. go into a
folder rather than responding if we are in File mode and the
selected file is a folder.
(get_selection): New helper function.
(add_bookmark_button_clicked_cb): Use get_selection().
(bookmarks_check_add_sensitivity): Likewise.
(gtk_file_chooser_default_get_paths): Likewise.
(check_save_entry): New helper function.
(gtk_file_chooser_default_get_paths): Use check_save_entry().
(selection_check): Renamed from selection_is_folders(). Now
checks whether the selection is empty, all files, all folders.
(bookmarks_check_add_sensitivity): Use selection_check().
Fri Mar 5 00:05:59 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtkcombobox.c (gtk_combo_box_list_setup):
......
......@@ -267,12 +267,14 @@ static gboolean gtk_file_chooser_default_remove_shortcut_folder (GtkFileCh
const GtkFilePath *path,
GError **error);
static GSList * gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser);
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_should_respond (GtkFileChooserEmbed *chooser_embed);
static void location_popup_handler (GtkFileChooserDefault *impl);
static void up_folder_handler (GtkFileChooserDefault *impl);
......@@ -502,6 +504,7 @@ 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->should_respond = gtk_file_chooser_default_should_respond;
}
static void
gtk_file_chooser_default_init (GtkFileChooserDefault *impl)
......@@ -1432,6 +1435,21 @@ shortcuts_add_bookmark_from_path (GtkFileChooserDefault *impl,
}
}
/* Returns the GtkTreeSelection that makes sense for the mode which the file chooser is in */
static GtkTreeSelection *
get_selection (GtkFileChooserDefault *impl)
{
GtkWidget *tree_view;
if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
tree_view = impl->browse_directories_tree_view;
else
tree_view = impl->browse_files_tree_view;
return gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
}
static void
add_bookmark_foreach_cb (GtkTreeModel *model,
GtkTreePath *path,
......@@ -1466,16 +1484,10 @@ static void
add_bookmark_button_clicked_cb (GtkButton *button,
GtkFileChooserDefault *impl)
{
GtkWidget *tree_view;
GtkTreeSelection *selection;
if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
tree_view = impl->browse_directories_tree_view;
else
tree_view = impl->browse_files_tree_view;
selection = get_selection (impl);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
if (gtk_tree_selection_count_selected_rows (selection) == 0)
shortcuts_add_bookmark_from_path (impl, impl->current_folder);
else
......@@ -1517,46 +1529,86 @@ remove_bookmark_button_clicked_cb (GtkButton *button,
}
}
struct is_folders_foreach_closure {
struct selection_check_closure {
GtkFileChooserDefault *impl;
gboolean empty;
gboolean all_files;
gboolean all_folders;
};
/* Used from gtk_tree_selection_selected_foreach() */
static void
is_folders_foreach_cb (GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data)
selection_check_foreach_cb (GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data)
{
struct is_folders_foreach_closure *closure;
struct selection_check_closure *closure;
GtkTreeIter child_iter;
const GtkFileInfo *info;
gboolean is_folder;
closure = data;
closure->empty = FALSE;
gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter);
info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter);
closure->all_folders &= gtk_file_info_get_is_folder (info);
is_folder = gtk_file_info_get_is_folder (info);
closure->all_folders &= is_folder;
closure->all_files &= !is_folder;
}
/* Returns whether the selected items in the file list are all folders */
static gboolean
selection_is_folders (GtkFileChooserDefault *impl)
/* Checks whether the selected items in the file list are all files or all folders */
static void
selection_check (GtkFileChooserDefault *impl,
gboolean *empty,
gboolean *all_files,
gboolean *all_folders)
{
struct is_folders_foreach_closure closure;
struct selection_check_closure closure;
GtkTreeSelection *selection;
closure.impl = impl;
closure.all_folders = TRUE;
if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
{
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_directories_tree_view));
if (gtk_tree_selection_count_selected_rows (selection) == 0)
closure.empty = TRUE;
else
{
closure.empty = FALSE;
closure.all_files = FALSE;
closure.all_folders = TRUE;
}
}
else
{
g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
|| impl->action == GTK_FILE_CHOOSER_ACTION_SAVE);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
gtk_tree_selection_selected_foreach (selection,
is_folders_foreach_cb,
&closure);
closure.impl = impl;
closure.empty = TRUE;
closure.all_files = TRUE;
closure.all_folders = TRUE;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
gtk_tree_selection_selected_foreach (selection,
selection_check_foreach_cb,
&closure);
}
return closure.all_folders;
g_assert (closure.empty || !(closure.all_files && closure.all_folders));
if (empty)
*empty = closure.empty;
if (all_files)
*all_files = closure.all_files;
if (all_folders)
*all_folders = closure.all_folders;
}
/* Sensitize the "add bookmark" button if all the selected items are folders, or
......@@ -1566,26 +1618,24 @@ selection_is_folders (GtkFileChooserDefault *impl)
static void
bookmarks_check_add_sensitivity (GtkFileChooserDefault *impl)
{
GtkWidget *tree_view;
GtkTreeSelection *selection;
gboolean active;
/* Check selection */
if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
tree_view = impl->browse_directories_tree_view;
else
tree_view = impl->browse_files_tree_view;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
selection = get_selection (impl);
if (gtk_tree_selection_count_selected_rows (selection) == 0)
active = (shortcut_find_position (impl, impl->current_folder) == -1);
else
active = (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER ||
selection_is_folders (impl));
{
gboolean all_folders;
selection_check (impl, NULL, NULL, &all_folders);
active = (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER ||
all_folders);
}
gtk_widget_set_sensitive (impl->browse_shortcuts_add_button, active);
}
......@@ -1833,7 +1883,7 @@ create_file_list (GtkFileChooserDefault *impl)
impl->browse_files_tree_view = gtk_tree_view_new ();
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (impl->browse_files_tree_view), TRUE);
gtk_container_add (GTK_CONTAINER (impl->browse_files_swin), impl->browse_files_tree_view);
g_signal_connect (impl->browse_files_tree_view, "row_activated",
g_signal_connect (impl->browse_files_tree_view, "row-activated",
G_CALLBACK (list_row_activated), impl);
gtk_widget_show (impl->browse_files_tree_view);
......@@ -2744,7 +2794,7 @@ set_list_model (GtkFileChooserDefault *impl)
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_NAME, GTK_SORT_ASCENDING);
impl->list_sort_ascending = TRUE;
g_signal_connect (impl->sort_model, "sort_column_changed",
g_signal_connect (impl->sort_model, "sort-column-changed",
G_CALLBACK (list_sort_column_changed_cb), impl);
gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
......@@ -3001,6 +3051,44 @@ gtk_file_chooser_default_unselect_all (GtkFileChooser *chooser)
gtk_tree_selection_unselect_all (selection);
}
/* Checks whether the filename entry for the Save modes contains a valid filename */
static GtkFilePath *
check_save_entry (GtkFileChooserDefault *impl,
gboolean *is_valid,
gboolean *is_empty)
{
const char *filename;
GtkFilePath *path;
GError *error;
g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
filename = gtk_entry_get_text (GTK_ENTRY (impl->save_file_name_entry));
if (!filename || filename[0] == '\0')
{
*is_valid = FALSE;
*is_empty = TRUE;
return NULL;
}
*is_empty = FALSE;
error = NULL;
path = gtk_file_system_make_path (impl->file_system, impl->current_folder, filename, &error);
if (!path)
{
error_building_filename_dialog (impl, impl->current_folder, filename, error);
*is_valid = FALSE;
return NULL;
}
*is_valid = TRUE;
return path;
}
struct get_paths_closure {
GtkFileChooserDefault *impl;
GSList *result;
......@@ -3049,49 +3137,22 @@ gtk_file_chooser_default_get_paths (GtkFileChooser *chooser)
info.result = NULL;
info.path_from_entry = NULL;
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
{
const char *filename;
filename = gtk_entry_get_text (GTK_ENTRY (impl->save_file_name_entry));
if (filename != NULL && filename[0] != '\0')
{
GtkFilePath *selected;
GError *error = NULL;
selected = gtk_file_system_make_path (impl->file_system, impl->current_folder, filename, &error);
gboolean is_valid, is_empty;
if (!selected)
{
error_building_filename_dialog (impl, impl->current_folder, filename, error);
return NULL;
}
info.path_from_entry = selected;
}
info.path_from_entry = check_save_entry (impl, &is_valid, &is_empty);
if (!is_valid && !is_empty)
return NULL;
}
if (!info.path_from_entry || impl->select_multiple)
{
GtkTreeSelection *selection;
selection = NULL;
if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
{
if (impl->browse_directories_model)
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_directories_tree_view));
}
else
{
if (impl->sort_model)
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
}
if (selection)
gtk_tree_selection_selected_foreach (selection, get_paths_foreach, &info);
selection = get_selection (impl);
gtk_tree_selection_selected_foreach (selection, get_paths_foreach, &info);
}
if (info.path_from_entry)
......@@ -3394,6 +3455,125 @@ gtk_file_chooser_default_get_resizable_hints (GtkFileChooserEmbed *chooser_embed
}
}
struct switch_folder_closure {
GtkFileChooserDefault *impl;
const GtkFilePath *path;
int num_selected;
};
/* Used from gtk_tree_selection_selected_foreach() in switch_to_selected_folder() */
static void
switch_folder_foreach_cb (GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data)
{
struct switch_folder_closure *closure;
GtkTreeIter child_iter;
closure = data;
gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter);
closure->path = _gtk_file_system_model_get_path (closure->impl->browse_files_model, &child_iter);
closure->num_selected++;
}
/* Changes to the selected folder in the list view */
static void
switch_to_selected_folder (GtkFileChooserDefault *impl)
{
GtkTreeSelection *selection;
struct switch_folder_closure closure;
g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
|| impl->action == GTK_FILE_CHOOSER_ACTION_SAVE);
/* We do this with foreach() rather than get_selected() as we may be in
* multiple selection mode
*/
closure.impl = impl;
closure.path = NULL;
closure.num_selected = 0;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
gtk_tree_selection_selected_foreach (selection, switch_folder_foreach_cb, &closure);
g_assert (closure.path && closure.num_selected == 1);
_gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), closure.path);
}
/* Implementation for GtkFileChooserEmbed::should_respond() */
static gboolean
gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed)
{
GtkFileChooserDefault *impl;
GtkTreeSelection *selection;
int num_selected;
impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
/* First, check the save entry. If it has a valid name, we are done */
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
{
GtkFilePath *path;
gboolean is_valid, is_empty;
path = check_save_entry (impl, &is_valid, &is_empty);
if (is_valid)
{
gtk_file_path_free (path);
return TRUE;
}
else if (!is_empty)
return FALSE;
}
/* Second, do we have an empty selection? */
selection = get_selection (impl);
num_selected = gtk_tree_selection_count_selected_rows (selection);
if (num_selected == 0)
return FALSE;
/* Third, should we return file names or folder names? */
if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
|| impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
{
gboolean all_files, all_folders;
selection_check (impl, NULL, &all_files, &all_folders);
if (num_selected == 1)
{
if (all_folders)
{
switch_to_selected_folder (impl);
return FALSE;
}
else if (all_files)
return TRUE;
}
else
return all_files;
}
else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
/* There can be no files selected in folder mode since we don't show them,
* anyway.
*/
return TRUE;
g_assert_not_reached ();
return FALSE;
}
static void
set_current_filter (GtkFileChooserDefault *impl,
GtkFileFilter *filter)
......
......@@ -61,6 +61,9 @@ static void gtk_file_chooser_dialog_get_property (GObject *obj
static void gtk_file_chooser_dialog_style_set (GtkWidget *widget,
GtkStyle *previous_style);
static void response_cb (GtkDialog *dialog,
gint response_id);
static GObjectClass *parent_class;
GType
......@@ -133,6 +136,14 @@ gtk_file_chooser_dialog_init (GtkFileChooserDialog *dialog)
dialog->priv->resize_vertically = TRUE;
gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
/* We do a signal connection here rather than overriding the method in
* class_init because GtkDialog::response is a RUN_LAST signal. We want *our*
* handler to be run *first*, regardless of whether the user installs response
* handlers of his own.
*/
g_signal_connect (dialog, "response",
G_CALLBACK (response_cb), NULL);
}
static void
......@@ -441,6 +452,29 @@ gtk_file_chooser_dialog_style_set (GtkWidget *widget,
gtk_box_set_spacing (GTK_BOX (dialog->action_area), 6);
}
/* GtkDialog::response handler */
static void
response_cb (GtkDialog *dialog,
gint response_id)
{
GtkFileChooserDialogPrivate *priv;
priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
/* Ugh, try to filter out cancel-type responses */
if (response_id == GTK_RESPONSE_NONE
|| response_id == GTK_RESPONSE_REJECT
|| response_id == GTK_RESPONSE_DELETE_EVENT
|| response_id == GTK_RESPONSE_CANCEL
|| response_id == GTK_RESPONSE_CLOSE
|| response_id == GTK_RESPONSE_NO
|| response_id == GTK_RESPONSE_HELP)
return;
if (!_gtk_file_chooser_embed_should_respond (GTK_FILE_CHOOSER_EMBED (priv->widget)))
g_signal_stop_emission_by_name (dialog, "response");
}
static GtkWidget *
gtk_file_chooser_dialog_new_valist (const gchar *title,
GtkWindow *parent,
......
......@@ -8,6 +8,7 @@ static void delegate_get_default_size (GtkFileChooserEmbed *chooser_embe
static void delegate_get_resizable_hints (GtkFileChooserEmbed *chooser_embed,
gboolean *resize_horizontally,
gboolean *resize_vertically);
static gboolean delegate_should_respond (GtkFileChooserEmbed *chooser_embed);
static void delegate_default_size_changed (GtkFileChooserEmbed *chooser_embed,
gpointer data);
......@@ -31,6 +32,7 @@ _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->should_respond = delegate_should_respond;
}
/**
......@@ -74,6 +76,12 @@ delegate_get_resizable_hints (GtkFileChooserEmbed *chooser_embed,
_gtk_file_chooser_embed_get_resizable_hints (get_delegate (chooser_embed), resize_horizontally, resize_vertically);
}
static gboolean
delegate_should_respond (GtkFileChooserEmbed *chooser_embed)
{
return _gtk_file_chooser_embed_should_respond (get_delegate (chooser_embed));
}
static void
delegate_default_size_changed (GtkFileChooserEmbed *chooser_embed,
gpointer data)
......@@ -135,6 +143,14 @@ _gtk_file_chooser_embed_get_default_size (GtkFileChooserEmbed *chooser_embed,
GTK_FILE_CHOOSER_EMBED_GET_IFACE (chooser_embed)->get_default_size (chooser_embed, default_width, default_height);
}
gboolean
_gtk_file_chooser_embed_should_respond (GtkFileChooserEmbed *chooser_embed)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER_EMBED (chooser_embed), FALSE);
return GTK_FILE_CHOOSER_EMBED_GET_IFACE (chooser_embed)->should_respond (chooser_embed);
}
void
_gtk_file_chooser_embed_get_resizable_hints (GtkFileChooserEmbed *chooser_embed,
gboolean *resize_horizontally,
......
......@@ -46,6 +46,8 @@ struct _GtkFileChooserEmbedIface
void (*get_resizable_hints) (GtkFileChooserEmbed *chooser_embed,
gboolean *resize_horizontally,
gboolean *resize_vertically);
gboolean (*should_respond) (GtkFileChooserEmbed *chooser_embed);
/* Signals
*/