Issue #1291 - Non-intrusive warning when saved XCF version...

...won't work with older GIMP?

Make gimp_image_get_xcf_version() return a "reason" string which lists
all reasons why the image can't be saved with compatibility for older
GIMP versions. Display the reason as tooltip on the compat hint label
in the save dialog.
This commit is contained in:
Michael Natterer 2018-06-06 23:08:33 +02:00
parent ea14ce7ff4
commit a4061a6b0d
4 changed files with 103 additions and 28 deletions

View File

@ -2340,11 +2340,22 @@ gint
gimp_image_get_xcf_version (GimpImage *image,
gboolean zlib_compression,
gint *gimp_version,
const gchar **version_string)
const gchar **version_string,
gchar **version_reason)
{
GList *layers;
GList *list;
gint version = 0; /* default to oldest */
GList *layers;
GList *list;
GList *reasons = NULL;
gint version = 0; /* default to oldest */
const gchar *enum_desc;
#define ADD_REASON(_reason) \
if (version_reason) { \
gchar *tmp = _reason; \
if (g_list_find_custom (reasons, tmp, (GCompareFunc) strcmp)) \
g_free (tmp); \
else \
reasons = g_list_prepend (reasons, (_reason)); }
/* need version 1 for colormaps */
if (gimp_image_get_colormap (image))
@ -2380,11 +2391,16 @@ gimp_image_get_xcf_version (GimpImage *image,
case GIMP_LAYER_MODE_HARDLIGHT_LEGACY:
break;
/* Since 2.8 */
/* Since 2.6 */
case GIMP_LAYER_MODE_SOFTLIGHT_LEGACY:
case GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY:
case GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY:
case GIMP_LAYER_MODE_COLOR_ERASE_LEGACY:
gimp_enum_get_value (GIMP_TYPE_LAYER_MODE,
gimp_layer_get_mode (layer),
NULL, NULL, &enum_desc, NULL);
ADD_REASON (g_strdup_printf (_("Layer mode '%s' was added in %s"),
enum_desc, "GIMP 2.6"));
version = MAX (2, version);
break;
@ -2394,6 +2410,11 @@ gimp_image_get_xcf_version (GimpImage *image,
case GIMP_LAYER_MODE_LCH_CHROMA:
case GIMP_LAYER_MODE_LCH_COLOR:
case GIMP_LAYER_MODE_LCH_LIGHTNESS:
gimp_enum_get_value (GIMP_TYPE_LAYER_MODE,
gimp_layer_get_mode (layer),
NULL, NULL, &enum_desc, NULL);
ADD_REASON (g_strdup_printf (_("Layer mode '%s' was added in %s"),
enum_desc, "GIMP 2.10"));
version = MAX (9, version);
break;
@ -2432,6 +2453,11 @@ gimp_image_get_xcf_version (GimpImage *image,
case GIMP_LAYER_MODE_MERGE:
case GIMP_LAYER_MODE_SPLIT:
case GIMP_LAYER_MODE_PASS_THROUGH:
gimp_enum_get_value (GIMP_TYPE_LAYER_MODE,
gimp_layer_get_mode (layer),
NULL, NULL, &enum_desc, NULL);
ADD_REASON (g_strdup_printf (_("Layer mode '%s' was added in %s"),
enum_desc, "GIMP 2.10"));
version = MAX (10, version);
break;
@ -2445,11 +2471,17 @@ gimp_image_get_xcf_version (GimpImage *image,
/* need version 3 for layer trees */
if (gimp_viewable_get_children (GIMP_VIEWABLE (layer)))
{
ADD_REASON (g_strdup_printf (_("Layer groups were added in %s"),
"GIMP 2.8"));
version = MAX (3, version);
/* need version 13 for group layers with masks */
if (gimp_layer_get_mask (layer))
version = MAX (13, version);
{
ADD_REASON (g_strdup_printf (_("Masks on layer groups were "
"added in %s"), "GIMP 2.10"));
version = MAX (13, version);
}
}
}
@ -2461,7 +2493,11 @@ gimp_image_get_xcf_version (GimpImage *image,
/* need version 7 for != 8-bit gamma images */
if (gimp_image_get_precision (image) != GIMP_PRECISION_U8_GAMMA)
version = MAX (7, version);
{
ADD_REASON (g_strdup_printf (_("High bit-depth images were added "
"in %s"), "GIMP 2.10"));
version = MAX (7, version);
}
/* need version 12 for > 8-bit images for proper endian swapping */
if (gimp_image_get_precision (image) > GIMP_PRECISION_U8_GAMMA)
@ -2482,7 +2518,13 @@ gimp_image_get_xcf_version (GimpImage *image,
* conservative estimate and should never fail
*/
if (gimp_object_get_memsize (GIMP_OBJECT (image), NULL) >= ((gint64) 1 << 32))
version = MAX (11, version);
{
ADD_REASON (g_strdup_printf (_("Support for image files larger than "
"4GB was added in %s"), "GIMP 2.10"));
version = MAX (11, version);
}
#undef ADD_REASON
switch (version)
{
@ -2513,6 +2555,24 @@ gimp_image_get_xcf_version (GimpImage *image,
break;
}
if (version_reason && reasons)
{
GString *reason = g_string_new (NULL);
reasons = g_list_sort (reasons, (GCompareFunc) strcmp);
for (list = reasons; list; list = g_list_next (list))
{
g_string_append (reason, list->data);
if (g_list_next (list))
g_string_append_c (reason, '\n');
}
g_list_free (reasons);
*version_reason = g_string_free (reason, FALSE);
}
return version;
}

View File

@ -174,7 +174,8 @@ void gimp_image_exported (GimpImage *image,
gint gimp_image_get_xcf_version (GimpImage *image,
gboolean zlib_compression,
gint *gimp_version,
const gchar **version_string);
const gchar **version_string,
gchar **version_reason);
void gimp_image_set_xcf_compression (GimpImage *image,
gboolean compression);

View File

@ -167,7 +167,10 @@ gimp_save_dialog_set_image (GimpSaveDialog *dialog,
const gchar *version_string;
gint rle_version;
gint zlib_version;
gchar *tooltip;
gchar *rle_reason = NULL;
gchar *zlib_reason = NULL;
gchar *compat_hint;
gchar *compat_tooltip;
g_return_if_fail (GIMP_IS_SAVE_DIALOG (dialog));
g_return_if_fail (GIMP_IS_IMAGE (image));
@ -251,36 +254,47 @@ gimp_save_dialog_set_image (GimpSaveDialog *dialog,
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);
gimp_image_get_xcf_version (image, FALSE, &rle_version,
&version_string, &rle_reason);
gimp_image_get_xcf_version (image, TRUE, &zlib_version,
NULL, &zlib_reason);
if (rle_version == zlib_version)
{
tooltip = g_strdup_printf (_("The image uses features from %s, disabling "
"compression won't make the XCF file "
"readable by older GIMP versions."),
version_string);
compat_hint =
g_strdup_printf (_("The image uses features from %s, disabling "
"compression won't make the XCF file "
"readable by older GIMP versions."),
version_string);
compat_tooltip = rle_reason;
g_free (zlib_reason);
}
else
{
tooltip = g_strdup_printf (_("Keep compression disabled to make the XCF "
"file readable by %s and later."),
version_string);
compat_hint =
g_strdup_printf (_("Keep compression disabled to make the XCF "
"file readable by %s and later."),
version_string);
compat_tooltip = zlib_reason;
g_free (rle_reason);
}
if (gimp_image_get_metadata (image))
{
gchar *temp_tooltip;
gchar *temp_hint;
temp_tooltip = g_strconcat (tooltip, "\n",
_("Metadata won't be visible in GIMP "
"older than version 2.10."), NULL);
g_free (tooltip);
tooltip = temp_tooltip;
temp_hint = g_strconcat (compat_hint, "\n",
_("Metadata won't be visible in GIMP "
"older than version 2.10."), NULL);
g_free (compat_hint);
compat_hint = temp_hint;
}
gtk_label_set_text (GTK_LABEL (dialog->compat_info), tooltip);
g_free (tooltip);
gtk_label_set_text (GTK_LABEL (dialog->compat_info), compat_hint);
g_free (compat_hint);
gimp_help_set_help_data (dialog->compat_info, compat_tooltip, NULL);
g_free (compat_tooltip);
gtk_widget_show (dialog->compression_toggle);
gtk_widget_show (dialog->compat_info);

View File

@ -374,7 +374,7 @@ xcf_save_stream (Gimp *gimp,
info.file_version = gimp_image_get_xcf_version (image,
info.compression ==
COMPRESS_ZLIB,
NULL, NULL);
NULL, NULL, NULL);
if (info.file_version >= 11)
info.bytes_per_offset = 8;