Reimplement the GtkFileChooserButton for import

One of the limitations of GtkFileChooserButton is that it only allows one
file to be chosen (so that it can display that file name in the button
after the file chooser dialog finishes). Since in the import dialog we
never want to show the button with the filename(s) filled in but want to
directly execute the import once files have been selected, I reimplemented
the button to simply open a multi file chooser when clicked and to then
run the import function if one or more file names were selected.

This does appear to require some more code but gets us a much more useful
and consistent implementation.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2012-09-15 15:12:30 -07:00
parent dea8d47b69
commit ca696dd0cd

View file

@ -1276,32 +1276,40 @@ static GtkEntry *dive_computer_device(GtkWidget *vbox)
return GTK_ENTRY(entry); return GTK_ENTRY(entry);
} }
/* once a file is selected in the FileChooserButton we want to exit the import dialog */ static void pick_import_files(GtkWidget *w, GSList **filelist)
static void on_file_set(GtkFileChooserButton *widget, gpointer _data)
{ {
GtkDialog *main_dialog = _data; GtkWidget *fs_dialog, *import;
const char *current_default;
gtk_dialog_response(main_dialog, GTK_RESPONSE_ACCEPT); char *current_def_dir;
}
static GtkWidget *xml_file_selector(GtkWidget *vbox, GtkWidget *main_dialog)
{
GtkWidget *hbox, *frame, *chooser, *dialog;
GtkFileFilter *filter; GtkFileFilter *filter;
struct stat sb;
hbox = gtk_hbox_new(FALSE, 6); *filelist = NULL;
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); fs_dialog = gtk_file_chooser_dialog_new("Choose Files to import",
frame = gtk_frame_new("XML file name");
gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, TRUE, 3);
dialog = gtk_file_chooser_dialog_new("Open XML File",
GTK_WINDOW(main_window), GTK_WINDOW(main_window),
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL); NULL);
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); import = gtk_widget_get_ancestor(w, GTK_TYPE_DIALOG);
gtk_window_set_accept_focus(GTK_WINDOW(import), FALSE);
/* I'm not sure what the best default path should be... */
if (existing_filename) {
current_def_dir = g_path_get_dirname(existing_filename);
} else {
current_default = subsurface_default_filename();
current_def_dir = g_path_get_dirname(current_default);
free((void *)current_default);
}
/* it's possible that the directory doesn't exist (especially for the default)
* For gtk's file select box to make sense we create it */
if (stat(current_def_dir, &sb) != 0)
g_mkdir(current_def_dir, S_IRWXU);
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fs_dialog), current_def_dir);
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(fs_dialog), TRUE);
filter = gtk_file_filter_new(); filter = gtk_file_filter_new();
gtk_file_filter_add_pattern(filter, "*.xml"); gtk_file_filter_add_pattern(filter, "*.xml");
gtk_file_filter_add_pattern(filter, "*.XML"); gtk_file_filter_add_pattern(filter, "*.XML");
@ -1309,15 +1317,33 @@ static GtkWidget *xml_file_selector(GtkWidget *vbox, GtkWidget *main_dialog)
gtk_file_filter_add_pattern(filter, "*.SDA"); gtk_file_filter_add_pattern(filter, "*.SDA");
gtk_file_filter_add_mime_type(filter, "text/xml"); gtk_file_filter_add_mime_type(filter, "text/xml");
gtk_file_filter_set_name(filter, "XML file"); gtk_file_filter_set_name(filter, "XML file");
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fs_dialog), filter);
gtk_widget_show_all(fs_dialog);
if (gtk_dialog_run(GTK_DIALOG(fs_dialog)) == GTK_RESPONSE_ACCEPT)
*filelist = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(fs_dialog));
free(current_def_dir);
gtk_widget_destroy(fs_dialog);
gtk_window_set_accept_focus(GTK_WINDOW(import), TRUE);
/* if we selected one or more files, pretent that we clicked OK in the import dialog */
if (*filelist != NULL)
gtk_dialog_response(GTK_DIALOG(import), GTK_RESPONSE_ACCEPT);
}
chooser = gtk_file_chooser_button_new_with_dialog(dialog); static void xml_file_selector(GtkWidget *vbox, GtkWidget *main_dialog, GSList **list)
g_signal_connect(G_OBJECT(chooser), "file-set", G_CALLBACK(on_file_set), main_dialog); {
GtkWidget *hbox, *frame, *chooser, *box;
gtk_file_chooser_button_set_width_chars(GTK_FILE_CHOOSER_BUTTON(chooser), 30); hbox = gtk_hbox_new(FALSE, 6);
gtk_container_add(GTK_CONTAINER(frame), chooser); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3);
return chooser; frame = gtk_frame_new("XML file name");
gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, TRUE, 3);
box = gtk_hbox_new(FALSE, 6);
gtk_container_add(GTK_CONTAINER(frame), box);
chooser = gtk_button_new_with_label("Pick XML file to import");
g_signal_connect(G_OBJECT(chooser), "clicked", G_CALLBACK(pick_import_files), list);
gtk_box_pack_start(GTK_BOX(box), chooser, FALSE, FALSE, 6);
} }
static void do_import_file(gpointer data, gpointer user_data) static void do_import_file(gpointer data, gpointer user_data)
@ -1360,9 +1386,9 @@ void import_dialog(GtkWidget *w, gpointer data)
{ {
int result; int result;
GtkWidget *dialog, *hbox, *vbox, *label, *info = NULL; GtkWidget *dialog, *hbox, *vbox, *label, *info = NULL;
GSList *filenames;
GtkComboBox *computer; GtkComboBox *computer;
GtkEntry *device; GtkEntry *device;
GtkWidget *XMLchooser;
device_data_t devicedata = { device_data_t devicedata = {
.devname = NULL, .devname = NULL,
}; };
@ -1377,7 +1403,7 @@ void import_dialog(GtkWidget *w, gpointer data)
vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
label = gtk_label_new("Import: \nLoad XML file or import directly from dive computer"); label = gtk_label_new("Import: \nLoad XML file or import directly from dive computer");
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 3); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 3);
XMLchooser = xml_file_selector(vbox, dialog); xml_file_selector(vbox, dialog, &filenames);
computer = dive_computer_selector(vbox); computer = dive_computer_selector(vbox);
device = dive_computer_device(vbox); device = dive_computer_device(vbox);
hbox = gtk_hbox_new(FALSE, 6); hbox = gtk_hbox_new(FALSE, 6);
@ -1392,14 +1418,13 @@ repeat:
dc_descriptor_t *descriptor; dc_descriptor_t *descriptor;
GtkTreeIter iter; GtkTreeIter iter;
GtkTreeModel *model; GtkTreeModel *model;
GSList *list;
case GTK_RESPONSE_ACCEPT: case GTK_RESPONSE_ACCEPT:
/* what happened - did the user pick a file? In that case /* what happened - did the user pick a file? In that case
* we ignore whether a dive computer model was picked */ * we ignore whether a dive computer model was picked */
if (info) if (info)
gtk_widget_destroy(info); gtk_widget_destroy(info);
list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(XMLchooser)); if (g_slist_length(filenames) == 0) {
if (g_slist_length(list) == 0) {
const char *vendor, *product; const char *vendor, *product;
if (!gtk_combo_box_get_active_iter(computer, &iter)) if (!gtk_combo_box_get_active_iter(computer, &iter))
@ -1422,8 +1447,8 @@ repeat:
if (info) if (info)
goto repeat; goto repeat;
} else { } else {
g_slist_foreach(list,do_import_file,NULL); g_slist_foreach(filenames,do_import_file,NULL);
g_slist_free(list); g_slist_free(filenames);
} }
break; break;
default: default: