Bug 736907 - Compat mode for XCF

- add gimp_image_get,get_xcf_compat_mode()
- add a compat toggle to GimpFileDialog which is shown and sensitive
  only for a save (not export), and if the image structure allows
  to save an old version at all. The button also has a tooltip
  which explains why it is sensitive and what it does
- add "gboolean xcf_compat" to file_save_dialog_save_image()
- in file_save_dialog_save_image(), call image_set_xcf_compat_mode(TRUE)
  only around the call to file_save() and set it to FALSE after saving
- in xcf_save_invoker(), honor the image's XCF compat flag and save an
  RLE-compressed XCF if possible

The above is very convoluted and doesn't pass the "xcf_compat" boolean
directly because we can't change the parameters of gimp-xcf-save, and
because the gimp-xcf-save might be called indirectly.
This commit is contained in:
Michael Natterer 2014-10-04 02:26:36 +02:00
parent 8b55983f7d
commit 950f753ede
9 changed files with 112 additions and 5 deletions

View File

@ -264,7 +264,8 @@ file_save_cmd_callback (GtkAction *action,
gimp, image, file,
save_proc,
GIMP_RUN_WITH_LAST_VALS,
TRUE, FALSE, FALSE, TRUE);
TRUE, FALSE, FALSE,
FALSE, TRUE);
break;
}
@ -338,7 +339,7 @@ file_save_cmd_callback (GtkAction *action,
GIMP_RUN_WITH_LAST_VALS,
FALSE,
overwrite, ! overwrite,
TRUE);
FALSE, TRUE);
}
}
break;

View File

@ -64,6 +64,8 @@ struct _GimpImagePrivate
GFile *save_a_copy_file; /* the image's save-a-copy file */
GFile *untitled_file; /* a file saying "Untitled" */
gboolean xcf_compat_mode; /* if possible, save compat XCF */
gint dirty; /* dirty flag -- # of ops */
gint64 dirty_time; /* time when image became dirty */
gint export_dirty; /* 'dirty' but for export */

View File

@ -2363,6 +2363,23 @@ gimp_image_get_xcf_version (GimpImage *image,
return version;
}
void
gimp_image_set_xcf_compat_mode (GimpImage *image,
gboolean compat_mode)
{
g_return_if_fail (GIMP_IS_IMAGE (image));
GIMP_IMAGE_GET_PRIVATE (image)->xcf_compat_mode = compat_mode;
}
gboolean
gimp_image_get_xcf_compat_mode (const GimpImage *image)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
return GIMP_IMAGE_GET_PRIVATE (image)->xcf_compat_mode;
}
void
gimp_image_set_resolution (GimpImage *image,
gdouble xresolution,

View File

@ -175,6 +175,10 @@ gint gimp_image_get_xcf_version (GimpImage *image,
gint *gimp_version,
const gchar **version_string);
void gimp_image_set_xcf_compat_mode (GimpImage *image,
gboolean compat_mode);
gboolean gimp_image_get_xcf_compat_mode (const GimpImage *image);
void gimp_image_set_resolution (GimpImage *image,
gdouble xres,
gdouble yres);

View File

@ -204,6 +204,7 @@ file_save_dialog_response (GtkWidget *save_dialog,
! dialog->save_a_copy && ! dialog->export,
FALSE,
dialog->export,
! dialog->export && dialog->compat,
FALSE))
{
/* Save was successful, now store the URI in a couple of
@ -742,6 +743,7 @@ file_save_dialog_save_image (GimpProgress *progress,
gboolean change_saved_state,
gboolean export_backward,
gboolean export_forward,
gboolean xcf_compat,
gboolean verbose_cancel)
{
GimpPDBStatusType status;
@ -756,11 +758,17 @@ file_save_dialog_save_image (GimpProgress *progress,
gimp_action_group_set_action_sensitive (list->data, "file-quit", FALSE);
}
if (xcf_compat)
gimp_image_set_xcf_compat_mode (image, TRUE);
status = file_save (gimp, image, progress, file,
save_proc, run_mode,
change_saved_state, export_backward, export_forward,
&error);
if (xcf_compat)
gimp_image_set_xcf_compat_mode (image, FALSE);
switch (status)
{
case GIMP_PDB_SUCCESS:

View File

@ -34,6 +34,7 @@ gboolean file_save_dialog_save_image (GimpProgress *progress_and_handl
gboolean save_a_copy,
gboolean export_backward,
gboolean export_forward,
gboolean xcf_compat,
gboolean verbose_cancel);

View File

@ -98,6 +98,7 @@ static void gimp_file_dialog_add_filters (GimpFileDialog *dialo
action,
GSList *file_procs,
GSList *file_procs_all_images);
static void gimp_file_dialog_add_compat_toggle (GimpFileDialog *dialog);
static void gimp_file_dialog_process_procedure (GimpPlugInProcedure
*file_proc,
GtkFileFilter **filter_out,
@ -114,6 +115,8 @@ static void gimp_file_dialog_selection_changed (GtkFileChooser *choos
static void gimp_file_dialog_update_preview (GtkFileChooser *chooser,
GimpFileDialog *dialog);
static void gimp_file_dialog_compat_toggled (GtkToggleButton *button,
GimpFileDialog *dialog);
static void gimp_file_dialog_proc_changed (GimpFileProcView *view,
GimpFileDialog *dialog);
@ -398,6 +401,13 @@ gimp_file_dialog_new (Gimp *gimp,
file_procs,
file_procs_all_images);
dialog->extra_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog),
dialog->extra_vbox);
gtk_widget_show (dialog->extra_vbox);
gimp_file_dialog_add_compat_toggle (dialog);
gimp_file_dialog_add_proc_selection (dialog, gimp, file_procs, automatic,
automatic_help_id);
@ -496,6 +506,11 @@ gimp_file_dialog_set_save_image (GimpFileDialog *dialog,
if (! export)
{
gint rle_version;
gint zlib_version;
const gchar *version_string;
gchar *tooltip;
/*
* Priority of default paths for Save:
*
@ -564,6 +579,32 @@ gimp_file_dialog_set_save_image (GimpFileDialog *dialog,
g_object_ref (ext_file);
else
ext_file = g_file_new_for_uri ("file:///we/only/care/about/extension.xcf");
gimp_image_get_xcf_version (image, FALSE, &rle_version, &version_string);
gimp_image_get_xcf_version (image, TRUE, &zlib_version, NULL);
if (rle_version == zlib_version)
{
gtk_widget_set_sensitive (dialog->compat_toggle, FALSE);
tooltip = g_strdup_printf (_("The image uses features from %s and "
"cannot be saved for older GIMP "
"versions."),
version_string);
}
else
{
gtk_widget_set_sensitive (dialog->compat_toggle, TRUE);
tooltip = g_strdup_printf (_("Disables compression to make the XCF "
"file readable by %s and later."),
version_string);
}
gimp_help_set_help_data (dialog->compat_toggle, tooltip, NULL);
g_free (tooltip);
gtk_widget_show (dialog->compat_toggle);
}
else /* if (export) */
{
@ -642,8 +683,13 @@ gimp_file_dialog_set_save_image (GimpFileDialog *dialog,
g_object_ref (ext_file);
else
ext_file = g_file_new_for_uri ("file:///we/only/care/about/extension.png");
gtk_widget_hide (dialog->compat_toggle);
}
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->compat_toggle),
FALSE);
if (ext_file)
{
GFile *tmp_file = file_utils_file_with_new_ext (name_file, ext_file);
@ -847,6 +893,17 @@ gimp_file_dialog_add_filters (GimpFileDialog *dialog,
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), all);
}
static void
gimp_file_dialog_add_compat_toggle (GimpFileDialog *dialog)
{
dialog->compat_toggle = gtk_check_button_new_with_label (_("Save this XCF file with maximum compatibility"));
gtk_box_pack_start (GTK_BOX (dialog->extra_vbox), dialog->compat_toggle,
FALSE, FALSE, 0);
g_signal_connect (dialog->compat_toggle, "toggled",
G_CALLBACK (gimp_file_dialog_compat_toggled),
dialog);
}
/**
* gimp_file_dialog_process_procedure:
@ -939,8 +996,8 @@ gimp_file_dialog_add_proc_selection (GimpFileDialog *dialog,
GtkWidget *scrolled_window;
dialog->proc_expander = gtk_expander_new_with_mnemonic (NULL);
gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog),
dialog->proc_expander);
gtk_box_pack_start (GTK_BOX (dialog->extra_vbox), dialog->proc_expander,
TRUE, TRUE, 0);
gtk_widget_show (dialog->proc_expander);
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
@ -981,6 +1038,13 @@ gimp_file_dialog_update_preview (GtkFileChooser *chooser,
gtk_file_chooser_get_preview_file (chooser));
}
static void
gimp_file_dialog_compat_toggled (GtkToggleButton *button,
GimpFileDialog *dialog)
{
dialog->compat = gtk_toggle_button_get_active (button);
}
static void
gimp_file_dialog_proc_changed (GimpFileProcView *view,
GimpFileDialog *dialog)

View File

@ -44,10 +44,13 @@ struct _GimpFileDialog
gboolean open_as_layers;
gboolean save_a_copy;
gboolean export;
gboolean compat;
gboolean close_after_saving;
GimpObject *display_to_close;
GtkWidget *thumb_box;
GtkWidget *extra_vbox;
GtkWidget *compat_toggle;
GtkWidget *proc_expander;
GtkWidget *proc_view;
GtkWidget *progress;

View File

@ -376,11 +376,18 @@ xcf_save_invoker (GimpProcedure *procedure,
if (info.output)
{
gboolean compat_mode = gimp_image_get_xcf_compat_mode (image);
info.gimp = gimp;
info.seekable = G_SEEKABLE (info.output);
info.progress = progress;
info.filename = filename;
info.compression = COMPRESS_ZLIB;
if (compat_mode)
info.compression = COMPRESS_RLE;
else
info.compression = COMPRESS_ZLIB;
info.file_version = gimp_image_get_xcf_version (image,
info.compression ==
COMPRESS_ZLIB,