The GTK+ file chooser already *includes* UI code to ask the user whether
they want to overwrite an existing file; just use that. (The Win32 file chooser also does that itself.) Just do UI for "do you want to overwrite this {user-immutable,unwritable} file?". svn path=/trunk/; revision=43381
This commit is contained in:
parent
6ba80adfed
commit
475b8d9bcd
|
@ -1258,8 +1258,10 @@ do_file_save_as(capture_file *cf)
|
|||
/* Default to saving in the file's current format. */
|
||||
|
||||
/* build the file selection */
|
||||
file_save_as_w = file_selection_new ("Wireshark: Save Capture File As",
|
||||
FILE_SELECTION_SAVE);
|
||||
file_save_as_w = file_selection_new("Wireshark: Save Capture File As",
|
||||
FILE_SELECTION_SAVE);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(file_save_as_w),
|
||||
TRUE);
|
||||
|
||||
/* Container for each row of widgets */
|
||||
|
||||
|
@ -1318,10 +1320,9 @@ do_file_save_as(capture_file *cf)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* If the file exists, ask the user whether they want to overwrite it
|
||||
and, if so and it's user-immutable or not writable, whether they
|
||||
want to override that. */
|
||||
if (!file_target_exist_ui(file_save_as_w, cf_name)) {
|
||||
/* If the file exists and it's user-immutable or not writable,
|
||||
ask the user whether they want to override that. */
|
||||
if (!file_target_unwritable_ui(file_save_as_w, cf_name)) {
|
||||
/* They don't. Let them try another file name or cancel. */
|
||||
g_free(cf_name);
|
||||
continue;
|
||||
|
@ -1434,8 +1435,10 @@ file_export_specified_packets_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
|
|||
range.include_dependents = TRUE;
|
||||
|
||||
/* build the file selection */
|
||||
file_export_specified_packets_w = file_selection_new ("Wireshark: Export Specified Packets",
|
||||
FILE_SELECTION_SAVE);
|
||||
file_export_specified_packets_w = file_selection_new("Wireshark: Export Specified Packets",
|
||||
FILE_SELECTION_SAVE);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(file_export_specified_packets_w),
|
||||
TRUE);
|
||||
|
||||
/* Container for each row of widgets */
|
||||
|
||||
|
@ -1542,10 +1545,9 @@ file_export_specified_packets_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* If the file exists, ask the user whether they want to overwrite it
|
||||
and, if so and it's user-immutable or not writable, whether they
|
||||
want to override that. */
|
||||
if (!file_target_exist_ui(file_export_specified_packets_w, cf_name)) {
|
||||
/* If the file exists and it's user-immutable or not writable,
|
||||
ask the user whether they want to override that. */
|
||||
if (!file_target_unwritable_ui(file_export_specified_packets_w, cf_name)) {
|
||||
/* They don't. Let them try another file name or cancel. */
|
||||
g_free(cf_name);
|
||||
continue;
|
||||
|
@ -1788,6 +1790,8 @@ file_color_export_cmd_cb(GtkWidget *w _U_, gpointer filter_list)
|
|||
|
||||
file_color_export_w = file_selection_new("Wireshark: Export Color Filters",
|
||||
FILE_SELECTION_SAVE);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(file_color_export_w),
|
||||
TRUE);
|
||||
|
||||
/* Container for each row of widgets */
|
||||
main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
|
||||
|
@ -1833,10 +1837,9 @@ file_color_export_cmd_cb(GtkWidget *w _U_, gpointer filter_list)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* If the file exists, ask the user whether they want to overwrite it
|
||||
and, if so and it's user-immutable or not writable, whether they
|
||||
want to override that. */
|
||||
if (!file_target_exist_ui(file_color_export_w, cf_name)) {
|
||||
/* If the file exists and it's user-immutable or not writable,
|
||||
ask the user whether they want to override that. */
|
||||
if (!file_target_unwritable_ui(file_color_export_w, cf_name)) {
|
||||
/* They don't. Let them try another file name or cancel. */
|
||||
g_free(cf_name);
|
||||
continue;
|
||||
|
|
|
@ -159,63 +159,18 @@ file_selection_set_extra_widget(GtkWidget *fs, GtkWidget *extra)
|
|||
|
||||
#ifndef _WIN32
|
||||
/* If the specified file doesn't exist, return TRUE.
|
||||
If it does exist, pop up and run the UI asking the user whether
|
||||
they want to overwrite a file and, if it's user-immutable or not
|
||||
writable, whether they want to overwrite it anyway, and return
|
||||
TRUE if the file should be overwritten and FALSE otherwise. */
|
||||
If it exists and is neither user-immutable nor not writable, return
|
||||
TRUE.
|
||||
Otherwise, as the user whether they want to overwrite it anyway, and
|
||||
return TRUE if the file should be overwritten and FALSE otherwise. */
|
||||
gboolean
|
||||
file_target_exist_ui(GtkWidget *chooser_w, char *cf_name)
|
||||
file_target_unwritable_ui(GtkWidget *chooser_w, char *cf_name)
|
||||
{
|
||||
GtkWidget *msg_dialog;
|
||||
gchar *display_basename;
|
||||
gint response;
|
||||
ws_statb64 statbuf;
|
||||
|
||||
if (!file_exists(cf_name)) {
|
||||
/* The target doesn't exist; don't bother the user. */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The file exists. Ask the user if they want to overwrite it.
|
||||
*
|
||||
* XXX - what if it's a symlink? TextEdit just blindly replaces
|
||||
* symlinks with files if you save over them, but gedit appears
|
||||
* to replace the *target* of the symlink. (To find the target,
|
||||
* use realpath() - it dates back to the SUSv2 and may be even
|
||||
* older.)
|
||||
*/
|
||||
display_basename = g_filename_display_basename(cf_name);
|
||||
msg_dialog = gtk_message_dialog_new(GTK_WINDOW(chooser_w),
|
||||
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_NONE,
|
||||
"A file named \"%s\" already exists. Do you want to replace it?",
|
||||
display_basename);
|
||||
g_free(display_basename);
|
||||
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(msg_dialog),
|
||||
"A file or folder with the same name already exists in that folder. "
|
||||
"Replacing it will overwrite its current contents.");
|
||||
|
||||
gtk_dialog_add_buttons(GTK_DIALOG(msg_dialog),
|
||||
#ifndef _WIN32
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
"Replace", GTK_RESPONSE_ACCEPT,
|
||||
#else
|
||||
"Replace", GTK_RESPONSE_ACCEPT,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
#endif
|
||||
NULL);
|
||||
gtk_dialog_set_default_response(GTK_DIALOG(msg_dialog), GTK_RESPONSE_CANCEL);
|
||||
|
||||
response = gtk_dialog_run(GTK_DIALOG(msg_dialog));
|
||||
gtk_widget_destroy(msg_dialog);
|
||||
|
||||
if (response != GTK_RESPONSE_ACCEPT) {
|
||||
/* The user doesn't want to overwrite this file. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check whether the file has all the write permission bits clear
|
||||
and, on systems that have the 4.4-Lite file flags, whether it
|
||||
has the "user immutable" flag set. Treat both of those as an
|
||||
|
@ -231,72 +186,78 @@ file_target_exist_ui(GtkWidget *chooser_w, char *cf_name)
|
|||
flag, as it can be set only by the superuser or by processes with
|
||||
CAP_LINUX_IMMUTABLE, so it sounds as if it's not intended for
|
||||
arbitrary users to set or clear. */
|
||||
if (ws_stat64(cf_name, &statbuf) != -1) {
|
||||
/* OK, we have the permission bits and, if HAVE_ST_FLAGS is defined,
|
||||
the flags. (If we don't, we don't worry about it.) */
|
||||
if (ws_stat64(cf_name, &statbuf) == -1) {
|
||||
/* Either the file doesn't exist or we can't get its attributes.
|
||||
In the former case, we have no reason to bother the user.
|
||||
In the latter case, we don't have enough information to
|
||||
know whether to bother the user, so we don't. */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* OK, we have the permission bits and, if HAVE_ST_FLAGS is defined,
|
||||
the flags. (If we don't, we don't worry about it.) */
|
||||
#ifdef HAVE_ST_FLAGS
|
||||
if (statbuf.st_flags & UF_IMMUTABLE) {
|
||||
display_basename = g_filename_display_basename(cf_name);
|
||||
msg_dialog = gtk_message_dialog_new(GTK_WINDOW(chooser_w),
|
||||
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_NONE,
|
||||
if (statbuf.st_flags & UF_IMMUTABLE) {
|
||||
display_basename = g_filename_display_basename(cf_name);
|
||||
msg_dialog = gtk_message_dialog_new(GTK_WINDOW(chooser_w),
|
||||
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_NONE,
|
||||
#ifdef __APPLE__
|
||||
/* Stuff in the OS X UI calls files with the "user immutable" bit
|
||||
"locked"; pre-OS X Mac software might have had that notion and
|
||||
called it "locked". */
|
||||
"The file \"%s\" is locked.",
|
||||
/* Stuff in the OS X UI calls files with the "user immutable" bit
|
||||
"locked"; pre-OS X Mac software might have had that notion and
|
||||
called it "locked". */
|
||||
"The file \"%s\" is locked.",
|
||||
#else /* __APPLE__ */
|
||||
/* Just call it "immutable" in *BSD. */
|
||||
"The file \"%s\" is immutable.",
|
||||
/* Just call it "immutable" in *BSD. */
|
||||
"The file \"%s\" is immutable.",
|
||||
#endif /* __APPLE__ */
|
||||
display_basename);
|
||||
g_free(display_basename);
|
||||
} else
|
||||
display_basename);
|
||||
g_free(display_basename);
|
||||
} else
|
||||
#endif /* HAVE_ST_FLAGS */
|
||||
if ((statbuf.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) == 0) {
|
||||
display_basename = g_filename_display_basename(cf_name);
|
||||
msg_dialog = gtk_message_dialog_new(GTK_WINDOW(chooser_w),
|
||||
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_NONE,
|
||||
"The file \"%s\" is read-only.",
|
||||
display_basename);
|
||||
g_free(display_basename);
|
||||
} else {
|
||||
/* No problem, just drive on. */
|
||||
msg_dialog = NULL;
|
||||
if ((statbuf.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) == 0) {
|
||||
display_basename = g_filename_display_basename(cf_name);
|
||||
msg_dialog = gtk_message_dialog_new(GTK_WINDOW(chooser_w),
|
||||
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_NONE,
|
||||
"The file \"%s\" is read-only.",
|
||||
display_basename);
|
||||
g_free(display_basename);
|
||||
} else {
|
||||
/* No problem, just drive on. */
|
||||
msg_dialog = NULL;
|
||||
}
|
||||
if (msg_dialog != NULL) {
|
||||
/* OK, ask the user if they want to overwrite the file. */
|
||||
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(msg_dialog),
|
||||
"Do you want to overwrite it anyway?");
|
||||
|
||||
gtk_dialog_add_buttons(GTK_DIALOG(msg_dialog),
|
||||
"Overwrite", GTK_RESPONSE_ACCEPT,
|
||||
"Don't overwrite", GTK_RESPONSE_REJECT,
|
||||
NULL);
|
||||
gtk_dialog_set_default_response(GTK_DIALOG(msg_dialog), GTK_RESPONSE_REJECT);
|
||||
|
||||
response = gtk_dialog_run(GTK_DIALOG(msg_dialog));
|
||||
gtk_widget_destroy(msg_dialog);
|
||||
|
||||
if (response != GTK_RESPONSE_ACCEPT) {
|
||||
/* The user doesn't want to overwrite this file. */
|
||||
return FALSE;
|
||||
}
|
||||
if (msg_dialog != NULL) {
|
||||
/* OK, ask the user if they want to overwrite the file. */
|
||||
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(msg_dialog),
|
||||
"Do you want to overwrite it anyway?");
|
||||
|
||||
gtk_dialog_add_buttons(GTK_DIALOG(msg_dialog),
|
||||
"Overwrite", GTK_RESPONSE_ACCEPT,
|
||||
"Don't overwrite", GTK_RESPONSE_REJECT,
|
||||
NULL);
|
||||
gtk_dialog_set_default_response(GTK_DIALOG(msg_dialog), GTK_RESPONSE_REJECT);
|
||||
|
||||
response = gtk_dialog_run(GTK_DIALOG(msg_dialog));
|
||||
gtk_widget_destroy(msg_dialog);
|
||||
|
||||
if (response != GTK_RESPONSE_ACCEPT) {
|
||||
/* The user doesn't want to overwrite this file. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ST_FLAGS
|
||||
/* OK, they want to overwrite the file. If it has the "user
|
||||
immutable" flag, we have to turn that off first, so we
|
||||
can move on top of, or overwrite, the file. */
|
||||
if (statbuf.st_flags & UF_IMMUTABLE) {
|
||||
/* If this fails, the attempt to save will fail, so just
|
||||
let that happen and pop up a "you lose" dialog. */
|
||||
chflags(cf_name, statbuf.st_flags & ~UF_IMMUTABLE);
|
||||
}
|
||||
#endif
|
||||
/* OK, they want to overwrite the file. If it has the "user
|
||||
immutable" flag, we have to turn that off first, so we
|
||||
can move on top of, or overwrite, the file. */
|
||||
if (statbuf.st_flags & UF_IMMUTABLE) {
|
||||
/* If this fails, the attempt to save will fail, so just
|
||||
let that happen and pop up a "you lose" dialog. */
|
||||
chflags(cf_name, statbuf.st_flags & ~UF_IMMUTABLE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -87,15 +87,15 @@ extern void file_selection_set_extra_widget(GtkWidget *fs, GtkWidget *extra);
|
|||
|
||||
#ifndef _WIN32
|
||||
/** If the specified file doesn't exist, return TRUE.
|
||||
* If it does exist, pop up and run the UI asking the user whether
|
||||
* they want to overwrite a file and, if it's user-immutable or not
|
||||
* writable, whether they want to overwrite it anyway, and return
|
||||
* TRUE if the file should be overwritten and FALSE otherwise.
|
||||
* If it exists and is neither user-immutable nor not writable, return
|
||||
* TRUE.
|
||||
* Otherwise, as the user whether they want to overwrite it anyway, and
|
||||
* return TRUE if the file should be overwritten and FALSE otherwise.
|
||||
*
|
||||
* @param chooser_w the GtkFileChooser used to select the file in question
|
||||
* @param cf_name the current name chosen
|
||||
*/
|
||||
extern gboolean file_target_exist_ui(GtkWidget *chooser_w, char *cf_name);
|
||||
extern gboolean file_target_unwritable_ui(GtkWidget *chooser_w, char *cf_name);
|
||||
#endif
|
||||
|
||||
/** The function file_selection_browse() will g_object_set_data() itself on it's parent window.
|
||||
|
|
Loading…
Reference in New Issue