removed file_save() and renamed file_save_as() to file_save() which always

2005-02-13  Michael Natterer  <mitch@gimp.org>

	* app/file/file-save.[ch]: removed file_save() and renamed
	file_save_as() to file_save() which always requires "uri" and
	"file_proc" to be passed. This functions does no more file_proc by
	extension finding and stuff.

	* app/actions/file-commands.c (file_save_cmd_callback): only call
	file_save() if the image has both uri and save_proc, fall back to
	file_save_as_cmd_callback() otherwise.

	* app/dialogs/file-save-dialog.c: completely chopped and
	reconstructed. Added tons of checks for extension vs. save_proc
	consistency and ask the user if she really wants to save weird
	stuff. Added masive debugging output because I'm far from certain
	that everything is correct.
This commit is contained in:
Michael Natterer 2005-02-13 18:05:43 +00:00 committed by Michael Natterer
parent aed06d70ba
commit 1c7e7a165a
5 changed files with 364 additions and 191 deletions

View file

@ -1,3 +1,20 @@
2005-02-13 Michael Natterer <mitch@gimp.org>
* app/file/file-save.[ch]: removed file_save() and renamed
file_save_as() to file_save() which always requires "uri" and
"file_proc" to be passed. This functions does no more file_proc by
extension finding and stuff.
* app/actions/file-commands.c (file_save_cmd_callback): only call
file_save() if the image has both uri and save_proc, fall back to
file_save_as_cmd_callback() otherwise.
* app/dialogs/file-save-dialog.c: completely chopped and
reconstructed. Added tons of checks for extension vs. save_proc
consistency and ask the user if she really wants to save weird
stuff. Added masive debugging output because I'm far from certain
that everything is correct.
2005-02-13 Sven Neumann <sven@gimp.org>
* libgimp*/Makefile.am: s/GIMP_THREAD_FLAGS/GTHREAD_CFLAGS/

View file

@ -181,18 +181,28 @@ file_save_cmd_callback (GtkAction *action,
gpointer data)
{
GimpDisplay *gdisp;
GimpImage *gimage;
return_if_no_display (gdisp, data);
if (! gimp_image_active_drawable (gdisp->gimage))
gimage = gdisp->gimage;
if (! gimp_image_active_drawable (gimage))
return;
/* Only save if the gimage has been modified */
if (gdisp->gimage->dirty ||
! GIMP_GUI_CONFIG (gdisp->gimage->gimp->config)->trust_dirty_flag)
if (gimage->dirty ||
! GIMP_GUI_CONFIG (gimage->gimp->config)->trust_dirty_flag)
{
const gchar *uri = gimp_object_get_name (GIMP_OBJECT (gdisp->gimage));
const gchar *uri;
PlugInProcDef *save_proc = NULL;
if (! uri)
uri = gimp_object_get_name (GIMP_OBJECT (gimage));
save_proc = gimp_image_get_save_proc (gimage);
if (uri && ! save_proc)
save_proc = file_utils_find_proc (gimage->gimp->save_procs, uri);
if (! (uri && save_proc))
{
file_save_as_cmd_callback (action, data);
}
@ -201,9 +211,10 @@ file_save_cmd_callback (GtkAction *action,
GimpPDBStatusType status;
GError *error = NULL;
status = file_save (gdisp->gimage, action_data_get_context (data),
status = file_save (gimage, action_data_get_context (data),
GIMP_PROGRESS (gdisp),
GIMP_RUN_WITH_LAST_VALS, &error);
uri, save_proc,
GIMP_RUN_WITH_LAST_VALS, FALSE, &error);
if (status != GIMP_PDB_SUCCESS &&
status != GIMP_PDB_CANCEL)

View file

@ -31,6 +31,8 @@
#include "core/gimpimage.h"
#include "core/gimpprogress.h"
#include "plug-in/plug-in-proc-def.h"
#include "file/file-save.h"
#include "file/file-utils.h"
@ -46,21 +48,22 @@
/* local function prototypes */
static void file_save_dialog_response (GtkWidget *save_dialog,
gint response_id,
Gimp *gimp);
static void file_save_overwrite (GtkWidget *save_dialog,
const gchar *uri,
const gchar *raw_filename);
static void file_save_overwrite_response (GtkWidget *dialog,
gint response_id,
gpointer data);
static gboolean file_save_dialog_save_image (GtkWidget *save_dialog,
GimpImage *gimage,
const gchar *uri,
const gchar *raw_filename,
PlugInProcDef *save_proc,
gboolean save_a_copy);
static void file_save_dialog_response (GtkWidget *save_dialog,
gint response_id,
Gimp *gimp);
static gboolean file_save_dialog_check_uri (GtkWidget *save_dialog,
Gimp *gimp,
gchar **uri,
PlugInProcDef **save_proc);
static gboolean file_save_dialog_use_extension (GtkWidget *save_dialog,
const gchar *uri);
static gboolean file_save_dialog_overwrite (GtkWidget *save_dialog,
const gchar *uri);
static gboolean file_save_dialog_save_image (GtkWidget *save_dialog,
GimpImage *gimage,
const gchar *uri,
PlugInProcDef *save_proc,
gboolean save_a_copy);
/* public functions */
@ -121,6 +124,7 @@ file_save_dialog_response (GtkWidget *save_dialog,
{
GimpFileDialog *dialog = GIMP_FILE_DIALOG (save_dialog);
gchar *uri;
PlugInProcDef *save_proc;
if (response_id != GTK_RESPONSE_OK)
{
@ -130,60 +134,298 @@ file_save_dialog_response (GtkWidget *save_dialog,
return;
}
gimp_file_dialog_set_sensitive (dialog, FALSE);
if (file_save_dialog_check_uri (save_dialog, gimp, &uri, &save_proc))
{
if (file_save_dialog_save_image (save_dialog,
dialog->gimage,
uri,
save_proc,
dialog->save_a_copy))
{
gtk_widget_hide (save_dialog);
}
g_free (uri);
}
gimp_file_dialog_set_sensitive (dialog, TRUE);
}
static gboolean
file_save_dialog_check_uri (GtkWidget *save_dialog,
Gimp *gimp,
gchar **ret_uri,
PlugInProcDef **ret_save_proc)
{
GimpFileDialog *dialog = GIMP_FILE_DIALOG (save_dialog);
gchar *uri;
gchar *basename;
PlugInProcDef *save_proc;
PlugInProcDef *uri_proc;
PlugInProcDef *basename_proc;
uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (save_dialog));
if (uri && strlen (uri))
{
if (gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (save_dialog), uri))
{
file_save_overwrite (save_dialog, uri, uri);
}
else
{
gimp_file_dialog_set_sensitive (dialog, FALSE);
if (! (uri && strlen (uri)))
return FALSE;
if (file_save_dialog_save_image (save_dialog,
dialog->gimage,
uri,
uri,
dialog->file_proc,
dialog->save_a_copy))
basename = g_path_get_basename (uri);
g_print ("\n\n%s: URI = %s\n", G_STRFUNC, uri);
save_proc = dialog->file_proc;
uri_proc = file_utils_find_proc (gimp->save_procs, uri);
basename_proc = file_utils_find_proc (gimp->save_procs, basename);
/* first check if the user entered an extension at all */
if (! basename_proc)
{
g_print ("%s: basename has no valid extension\n",
G_STRFUNC);
if (! strchr (basename, '.'))
{
const gchar *ext = NULL;
g_print ("%s: basename has no '.', trying to add extension\n",
G_STRFUNC);
if (! save_proc)
{
gtk_widget_hide (save_dialog);
ext = "xcf";
}
else if (save_proc->extensions_list)
{
ext = save_proc->extensions_list->data;
}
gimp_file_dialog_set_sensitive (dialog, TRUE);
if (ext)
{
gchar *ext_uri = g_strconcat (uri, ".", ext, NULL);
gchar *ext_basename = g_strconcat (basename, ".", ext, NULL);
g_print ("%s: appending .%s to basename without any extension\n",
G_STRFUNC, ext);
g_free (uri);
g_free (basename);
uri = ext_uri;
basename = ext_basename;
uri_proc = file_utils_find_proc (gimp->save_procs, uri);
basename_proc = file_utils_find_proc (gimp->save_procs, basename);
}
else
{
g_print ("%s: save_proc has no extensions, continuing without\n",
G_STRFUNC);
/* there may be file formats with no extension at all, use
* the selected proc in this case.
*/
basename_proc = save_proc;
if (! uri_proc)
uri_proc = basename_proc;
}
if (! basename_proc)
{
g_print ("%s: unable to figure save_proc, bailing out\n",
G_STRFUNC);
g_message (_("The given filename does not have any known "
"file extension. Please enter a known file "
"extension or select a file format from the "
"file format list."));
g_free (uri);
g_free (basename);
return FALSE;
}
}
else if (save_proc && ! save_proc->extensions_list)
{
g_print ("%s: basename has '.', but save_proc has no extensions, "
"accepting random extension\n",
G_STRFUNC);
/* accept any random extension if the file format has
* no extensions at all
*/
basename_proc = save_proc;
if (! uri_proc)
uri_proc = basename_proc;
}
}
g_free (uri);
/* then check if the selected format matches the entered extension */
if (! save_proc)
{
g_print ("%s: no save_proc was selected from the list\n",
G_STRFUNC);
if (! basename_proc)
{
g_print ("%s: basename had no useful extension, bailing out\n",
G_STRFUNC);
g_message (_("The given filename does not have any known "
"file extension. Please enter a known file "
"extension or select a file format from the "
"file format list."));
g_free (uri);
g_free (basename);
return FALSE;
}
g_print ("%s: use URI's proc '%s' so indirect saving works\n",
G_STRFUNC, uri_proc->menu_label);
/* use the URI's proc if no save proc was selected */
save_proc = uri_proc;
}
else
{
g_print ("%s: save_proc '%s' was selected from the list\n",
G_STRFUNC, save_proc->menu_label);
if (save_proc != basename_proc)
{
g_print ("%s: however the basename's proc is '%s'\n",
G_STRFUNC,
basename_proc ? basename_proc->menu_label : "NULL");
if (uri_proc != basename_proc)
{
g_print ("%s: that's impossible for remote URIs, bailing out\n",
G_STRFUNC);
/* remote URI */
g_message (_("Saving remote files needs to determine the "
"file format from the file extension. Please "
"enter a file extension that matches the selected "
"file format or enter no file extension at all."));
g_free (uri);
g_free (basename);
return FALSE;
}
else
{
g_print ("%s: ask the user if she really wants that filename\n",
G_STRFUNC);
/* local URI */
if (! file_save_dialog_use_extension (save_dialog, uri))
{
g_free (uri);
g_free (basename);
return FALSE;
}
}
}
else if (save_proc != uri_proc)
{
g_print ("%s: use URI's proc '%s' so indirect saving works\n",
G_STRFUNC, uri_proc->menu_label);
/* need to use the URI's proc for saving because e.g.
* the GIF plug-in can't save a GIF to sftp://
*/
save_proc = uri_proc;
}
}
if (! save_proc)
{
g_print ("%s: EEEEEEK\n", G_STRFUNC);
g_message ("Yay! You found a bug. Please report this at "
"http://bugzilla.gnome.org/ and paste the console "
"output to the 'Additional Comments' field");
return FALSE;
}
if (gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (save_dialog), uri))
{
if (! file_save_dialog_overwrite (save_dialog, uri))
{
g_free (uri);
g_free (basename);
return FALSE;
}
}
g_free (basename);
*ret_uri = uri;
*ret_save_proc = save_proc;
return TRUE;
}
typedef struct _OverwriteData OverwriteData;
struct _OverwriteData
static gboolean
file_save_dialog_use_extension (GtkWidget *save_dialog,
const gchar *uri)
{
GtkWidget *save_dialog;
gchar *uri;
gchar *raw_filename;
};
GtkWidget *dialog;
gboolean use_name = FALSE;
static void
file_save_overwrite (GtkWidget *save_dialog,
const gchar *uri,
const gchar *raw_filename)
dialog = gimp_message_dialog_new (_("Extension Mismatch"),
GIMP_STOCK_QUESTION,
save_dialog, GTK_DIALOG_DESTROY_WITH_PARENT,
gimp_standard_help_func, NULL,
GTK_STOCK_NO, GTK_RESPONSE_CANCEL,
GTK_STOCK_YES, GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (dialog)->box,
_("The given file extension does "
"not match the chosen file type."));
gimp_message_box_set_text (GIMP_MESSAGE_DIALOG (dialog)->box,
_("Do you want to use this name anyway?"));
gtk_dialog_set_response_sensitive (GTK_DIALOG (save_dialog),
GTK_RESPONSE_CANCEL, FALSE);
g_object_ref (dialog);
use_name = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
gtk_widget_destroy (dialog);
g_object_unref (dialog);
gtk_dialog_set_response_sensitive (GTK_DIALOG (save_dialog),
GTK_RESPONSE_CANCEL, TRUE);
return use_name;
}
static gboolean
file_save_dialog_overwrite (GtkWidget *save_dialog,
const gchar *uri)
{
OverwriteData *overwrite_data = g_new0 (OverwriteData, 1);
GtkWidget *dialog;
gchar *filename;
overwrite_data->save_dialog = save_dialog;
overwrite_data->uri = g_strdup (uri);
overwrite_data->raw_filename = g_strdup (raw_filename);
GtkWidget *dialog;
gchar *filename;
gboolean overwrite = FALSE;
dialog =
gimp_message_dialog_new (_("File exists"), GIMP_STOCK_WARNING,
save_dialog, 0,
save_dialog, GTK_DIALOG_DESTROY_WITH_PARENT,
gimp_standard_help_func, NULL,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
@ -196,10 +438,6 @@ file_save_overwrite (GtkWidget *save_dialog,
GTK_RESPONSE_CANCEL,
-1);
g_signal_connect (dialog, "response",
G_CALLBACK (file_save_overwrite_response),
overwrite_data);
filename = file_utils_uri_to_utf8_filename (uri);
gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (dialog)->box,
_("A file named '%s' already exists."),
@ -210,51 +448,26 @@ file_save_overwrite (GtkWidget *save_dialog,
_("Do you want to replace it with the image "
"you are saving?"));
gimp_file_dialog_set_sensitive (GIMP_FILE_DIALOG (save_dialog), FALSE);
gtk_dialog_set_response_sensitive (GTK_DIALOG (save_dialog),
GTK_RESPONSE_CANCEL, FALSE);
gtk_widget_show (dialog);
}
g_object_ref (dialog);
static void
file_save_overwrite_response (GtkWidget *dialog,
gint response_id,
gpointer data)
{
OverwriteData *overwrite_data = data;
GimpFileDialog *save_dialog = GIMP_FILE_DIALOG (overwrite_data->save_dialog);
overwrite = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
gtk_widget_destroy (dialog);
g_object_unref (dialog);
gtk_dialog_set_response_sensitive (GTK_DIALOG (save_dialog),
GTK_RESPONSE_CANCEL, TRUE);
gtk_widget_destroy (dialog);
if (response_id == GTK_RESPONSE_OK)
{
if (file_save_dialog_save_image (overwrite_data->save_dialog,
save_dialog->gimage,
overwrite_data->uri,
overwrite_data->raw_filename,
save_dialog->file_proc,
save_dialog->save_a_copy))
{
gtk_widget_hide (overwrite_data->save_dialog);
}
}
gimp_file_dialog_set_sensitive (save_dialog, TRUE);
g_free (overwrite_data->uri);
g_free (overwrite_data->raw_filename);
g_free (overwrite_data);
return overwrite;
}
static gboolean
file_save_dialog_save_image (GtkWidget *save_dialog,
GimpImage *gimage,
const gchar *uri,
const gchar *raw_filename,
PlugInProcDef *save_proc,
gboolean save_a_copy)
{
@ -263,15 +476,10 @@ file_save_dialog_save_image (GtkWidget *save_dialog,
g_object_ref (gimage);
status = file_save_as (gimage,
gimp_get_user_context (gimage->gimp),
GIMP_PROGRESS (save_dialog),
uri,
raw_filename,
save_proc,
GIMP_RUN_INTERACTIVE,
save_a_copy,
&error);
status = file_save (gimage, gimp_get_user_context (gimage->gimp),
GIMP_PROGRESS (save_dialog),
uri, save_proc,
GIMP_RUN_INTERACTIVE, save_a_copy, &error);
if (status == GIMP_PDB_SUCCESS)
g_object_set_data_full (G_OBJECT (gimage->gimp), "gimp-file-save-last-uri",

View file

@ -67,42 +67,14 @@
/* public functions */
GimpPDBStatusType
file_save (GimpImage *gimage,
GimpContext *context,
GimpProgress *progress,
GimpRunMode run_mode,
GError **error)
{
const gchar *uri;
PlugInProcDef *file_proc;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), GIMP_PDB_CALLING_ERROR);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), GIMP_PDB_CALLING_ERROR);
g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress),
GIMP_PDB_CALLING_ERROR);
g_return_val_if_fail (error == NULL || *error == NULL,
GIMP_PDB_CALLING_ERROR);
uri = gimp_object_get_name (GIMP_OBJECT (gimage));
g_return_val_if_fail (uri != NULL, GIMP_PDB_CALLING_ERROR);
file_proc = gimp_image_get_save_proc (gimage);
return file_save_as (gimage, context, progress,
uri, uri, file_proc, run_mode, FALSE, error);
}
GimpPDBStatusType
file_save_as (GimpImage *gimage,
GimpContext *context,
GimpProgress *progress,
const gchar *uri,
const gchar *raw_filename,
PlugInProcDef *file_proc,
GimpRunMode run_mode,
gboolean save_a_copy,
GError **error)
file_save (GimpImage *gimage,
GimpContext *context,
GimpProgress *progress,
const gchar *uri,
PlugInProcDef *file_proc,
GimpRunMode run_mode,
gboolean save_a_copy,
GError **error)
{
const ProcRecord *proc;
Argument *args;
@ -110,45 +82,20 @@ file_save_as (GimpImage *gimage,
GimpPDBStatusType status;
gint i;
gchar *filename = NULL;
gchar *raw_filename_with_ext;
gchar *uri_with_ext;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), GIMP_PDB_CALLING_ERROR);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), GIMP_PDB_CALLING_ERROR);
g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress),
GIMP_PDB_CALLING_ERROR);
g_return_val_if_fail (uri != NULL, GIMP_PDB_CALLING_ERROR);
g_return_val_if_fail (raw_filename != NULL, GIMP_PDB_CALLING_ERROR);
g_return_val_if_fail (file_proc != NULL, GIMP_PDB_CALLING_ERROR);
g_return_val_if_fail (error == NULL || *error == NULL,
GIMP_PDB_CALLING_ERROR);
if (! gimp_image_active_drawable (gimage))
return GIMP_PDB_EXECUTION_ERROR;
if (strchr (raw_filename, '.'))
{
raw_filename_with_ext = g_strdup (raw_filename);
uri_with_ext = g_strdup (uri);
}
else
{
raw_filename_with_ext = g_strconcat (raw_filename, ".xcf", NULL);
uri_with_ext = g_strconcat (uri, ".xcf", NULL);
}
if (! file_proc)
file_proc = file_utils_find_proc (gimage->gimp->save_procs,
raw_filename_with_ext);
if (! file_proc)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Unknown file type"));
status = GIMP_PDB_CALLING_ERROR;
goto out;
}
filename = file_utils_filename_from_uri (uri_with_ext);
filename = file_utils_filename_from_uri (uri);
if (filename)
{
@ -187,8 +134,8 @@ file_save_as (GimpImage *gimage,
args[1].value.pdb_int = gimp_image_get_ID (gimage);
args[2].value.pdb_int =
gimp_item_get_ID (GIMP_ITEM (gimp_image_active_drawable (gimage)));
args[3].value.pdb_pointer = (filename ? filename : uri_with_ext);
args[4].value.pdb_pointer = raw_filename_with_ext;
args[3].value.pdb_pointer = filename ? filename : (gchar *) uri;
args[4].value.pdb_pointer = (gchar *) uri;
return_vals = procedural_db_execute (gimage->gimp, context, progress,
proc->name, args);
@ -204,30 +151,29 @@ file_save_as (GimpImage *gimage,
{
/* remember the "save-a-copy" filename for the next invocation */
g_object_set_data_full (G_OBJECT (gimage), "gimp-image-save-a-copy",
g_strdup (uri_with_ext),
g_strdup (uri),
(GDestroyNotify) g_free);
}
else
{
/* reset the "save-a-copy" filename when the image URI changes */
if (uri_with_ext &&
strcmp (uri_with_ext, gimp_image_get_uri (gimage)))
if (strcmp (uri, gimp_image_get_uri (gimage)))
g_object_set_data (G_OBJECT (gimage),
"gimp-image-save-a-copy", NULL);
gimp_image_set_uri (gimage, uri_with_ext);
gimp_image_set_uri (gimage, uri);
gimp_image_set_save_proc (gimage, file_proc);
gimp_image_clean_all (gimage);
}
documents = GIMP_DOCUMENT_LIST (gimage->gimp->documents);
imagefile = gimp_document_list_add_uri (documents,
uri_with_ext,
uri,
file_proc->mime_type);
gimp_imagefile_save_thumbnail (imagefile, file_proc->mime_type, gimage);
gimp_recent_list_add_uri (uri_with_ext, file_proc->mime_type);
gimp_recent_list_add_uri (uri, file_proc->mime_type);
}
else if (status != GIMP_PDB_CANCEL)
{
@ -242,9 +188,6 @@ file_save_as (GimpImage *gimage,
out:
g_free (filename);
g_free (raw_filename_with_ext);
g_free (uri_with_ext);
return status;
}

View file

@ -22,20 +22,14 @@
#define __FILE_SAVE_H__
GimpPDBStatusType file_save (GimpImage *gimage,
GimpContext *context,
GimpProgress *progress,
GimpRunMode run_mode,
GError **error);
GimpPDBStatusType file_save_as (GimpImage *gimage,
GimpContext *context,
GimpProgress *progress,
const gchar *uri,
const gchar *raw_filename,
PlugInProcDef *file_proc,
GimpRunMode run_mode,
gboolean save_a_copy,
GError **error);
GimpPDBStatusType file_save (GimpImage *gimage,
GimpContext *context,
GimpProgress *progress,
const gchar *uri,
PlugInProcDef *file_proc,
GimpRunMode run_mode,
gboolean save_a_copy,
GError **error);
#endif /* __FILE_SAVE_H__ */