Commit f4ce57aa authored by Michael Natterer's avatar Michael Natterer 😴
Browse files

Bug 676566 - Window title becomes "Untitled" after exporting without saving

Fix this and other issues more globally by moving the logic that
formats the image's display name into the GimpImage object, and return
the properly formatted name, e.g. "Foo.xcf", or "[Foo] (imported)"
from gimp_image_get_display_name().

Also add gimp_image_get_display_path() which returns the full path
instead. Use the two functions for formatting the image title, and
apply various other fixes that make sure the UI always uses the same
string to identify the image.

Call gimp_object_name_changed() whenever the save/export status
changes, so the image's cached display name and path get cleared.

(cherry picked from commit 220b2867)
parent 80579088
......@@ -39,8 +39,6 @@
#include "core/gimpprojectable.h"
#include "core/gimpprojection.h"
#include "file/file-utils.h"
#include "gegl/gimp-gegl-utils.h"
#include "display/gimpdisplay.h"
......@@ -351,7 +349,7 @@ debug_show_image_graph (GimpImage *source_image)
/* Create a new image of the result */
tiles = gimp_buffer_to_tiles (buffer);
new_name = g_strdup_printf ("%s GEGL graph",
file_utils_uri_display_name (gimp_image_get_uri_or_untitled (source_image)));
gimp_image_get_display_name (source_image));
new_image = gimp_create_image (gimp,
tile_manager_width (tiles),
tile_manager_height (tiles),
......
......@@ -403,7 +403,6 @@ file_revert_cmd_callback (GtkAction *action,
}
else
{
gchar *basename;
gchar *filename;
dialog =
......@@ -430,14 +429,13 @@ file_revert_cmd_callback (GtkAction *action,
G_CALLBACK (file_revert_confirm_response),
display);
basename = file_utils_uri_display_basename (uri);
filename = file_utils_uri_display_name (uri);
gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (dialog)->box,
_("Revert '%s' to '%s'?"),
basename, filename);
gimp_image_get_display_name (image),
filename);
g_free (filename);
g_free (basename);
gimp_message_box_set_text (GIMP_MESSAGE_DIALOG (dialog)->box,
_("By reverting the image to the state saved "
......
......@@ -33,8 +33,6 @@
#include "core/gimpimage.h"
#include "core/gimplist.h"
#include "file/file-utils.h"
#include "widgets/gimpactiongroup.h"
#include "widgets/gimpdialogfactory.h"
#include "widgets/gimpdock.h"
......@@ -295,19 +293,12 @@ windows_actions_image_notify (GimpDisplay *display,
}
{
const gchar *uri;
gchar *filename;
gchar *basename;
const gchar *display_name;
gchar *escaped;
gchar *title;
uri = gimp_image_get_uri_or_untitled (image);
filename = file_utils_uri_display_name (uri);
basename = file_utils_uri_display_basename (uri);
escaped = gimp_escape_uline (basename);
g_free (basename);
display_name = gimp_image_get_display_name (image);
escaped = gimp_escape_uline (display_name);
title = g_strdup_printf ("%s-%d.%d", escaped,
gimp_image_get_ID (image),
......@@ -316,12 +307,11 @@ windows_actions_image_notify (GimpDisplay *display,
g_object_set (action,
"label", title,
"tooltip", filename,
"tooltip", gimp_image_get_display_path (image),
"viewable", image,
"context", gimp_get_user_context (group->gimp),
NULL);
g_free (filename);
g_free (title);
}
......
......@@ -40,6 +40,7 @@ struct _GimpImagePrivate
GimpPlugInProcedure *save_proc; /* last save procedure used */
gchar *display_name; /* display basename */
gchar *display_path; /* display full path */
gint width; /* width in pixels */
gint height; /* height in pixels */
gdouble xresolution; /* image x-res, in dpi */
......
......@@ -994,6 +994,12 @@ gimp_image_finalize (GObject *object)
private->display_name = NULL;
}
if (private->display_path)
{
g_free (private->display_path);
private->display_path = NULL;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
......@@ -1013,6 +1019,12 @@ gimp_image_name_changed (GimpObject *object)
private->display_name = NULL;
}
if (private->display_path)
{
g_free (private->display_path);
private->display_path = NULL;
}
/* We never want the empty string as a name, so change empty strings
* to NULL strings (without emitting the "name-changed" signal
* again)
......@@ -1140,9 +1152,7 @@ gimp_image_get_description (GimpViewable *viewable,
GimpImage *image = GIMP_IMAGE (viewable);
if (tooltip)
{
*tooltip = file_utils_uri_display_name (gimp_image_get_uri_or_untitled (image));
}
*tooltip = g_strdup (gimp_image_get_display_path (image));
return g_strdup_printf ("%s-%d",
gimp_image_get_display_name (image),
......@@ -1626,8 +1636,7 @@ gimp_image_get_save_a_copy_uri (const GimpImage *image)
* @image: A #GimpImage.
*
* Returns: The XCF file URI, the imported file URI, or the exported
* file URI, in that order of precedence. Only to help implement
* backwards compatibility with GIMP 2.6 API.
* file URI, in that order of precedence.
**/
const gchar *
gimp_image_get_any_uri (const GimpImage *image)
......@@ -1667,6 +1676,8 @@ gimp_image_set_imported_uri (GimpImage *image,
g_object_set_data_full (G_OBJECT (image), GIMP_FILE_IMPORT_SOURCE_URI_KEY,
g_strdup (uri), (GDestroyNotify) g_free);
gimp_object_name_changed (GIMP_OBJECT (image));
}
/**
......@@ -1689,6 +1700,8 @@ gimp_image_set_exported_uri (GimpImage *image,
g_object_set_data_full (G_OBJECT (image),
GIMP_FILE_EXPORT_URI_KEY,
g_strdup (uri), (GDestroyNotify) g_free);
gimp_object_name_changed (GIMP_OBJECT (image));
}
/**
......@@ -1728,6 +1741,95 @@ gimp_image_get_filename (const GimpImage *image)
return g_filename_from_uri (uri, NULL, NULL);
}
static gchar *
gimp_image_format_display_uri (GimpImage *image,
gboolean basename)
{
const gchar *uri_format = NULL;
const gchar *export_status = NULL;
const gchar *uri;
const gchar *source;
const gchar *dest;
gboolean is_imported;
gboolean is_exported;
gchar *display_uri = NULL;
gchar *format_string;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
uri = gimp_image_get_uri (image);
source = gimp_image_get_imported_uri (image);
dest = gimp_image_get_exported_uri (image);
is_imported = (source != NULL);
is_exported = (dest != NULL);
if (uri)
{
display_uri = g_strdup (uri);
uri_format = "%s";
}
else
{
if (is_imported)
display_uri = g_strdup (source);
/* Calculate filename suffix */
if (! gimp_image_is_export_dirty (image))
{
if (is_exported)
{
display_uri = g_strdup (dest);
export_status = _(" (exported)");
}
else if (is_imported)
{
export_status = _(" (overwritten)");
}
else
{
g_warning ("Unexpected code path, Save+export implementation is buggy!");
}
}
else if (is_imported)
{
export_status = _(" (imported)");
}
if (display_uri)
{
gchar *tmp = file_utils_uri_with_new_ext (display_uri, NULL);
g_free (display_uri);
display_uri = tmp;
}
uri_format = "[%s]";
}
if (! display_uri)
{
display_uri = g_strdup (gimp_image_get_string_untitled ());
}
else if (basename)
{
gchar *tmp = file_utils_uri_display_basename (display_uri);
g_free (display_uri);
display_uri = tmp;
}
else
{
gchar *tmp = file_utils_uri_display_name (display_uri);
g_free (display_uri);
display_uri = tmp;
}
format_string = g_strconcat (uri_format, export_status, NULL);
display_uri = g_strdup_printf (format_string, display_uri);
g_free (format_string);
return display_uri;
}
const gchar *
gimp_image_get_display_name (GimpImage *image)
{
......@@ -1738,15 +1840,26 @@ gimp_image_get_display_name (GimpImage *image)
private = GIMP_IMAGE_GET_PRIVATE (image);
if (! private->display_name)
{
const gchar *uri = gimp_image_get_uri_or_untitled (image);
private->display_name = file_utils_uri_display_basename (uri);
}
private->display_name = gimp_image_format_display_uri (image, TRUE);
return private->display_name;
}
const gchar *
gimp_image_get_display_path (GimpImage *image)
{
GimpImagePrivate *private;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
private = GIMP_IMAGE_GET_PRIVATE (image);
if (! private->display_path)
private->display_path = gimp_image_format_display_uri (image, FALSE);
return private->display_path;
}
void
gimp_image_set_load_proc (GimpImage *image,
GimpPlugInProcedure *proc)
......
......@@ -191,6 +191,7 @@ void gimp_image_set_filename (GimpImage *image,
gchar * gimp_image_get_filename (const GimpImage *image);
const gchar * gimp_image_get_display_name (GimpImage *image);
const gchar * gimp_image_get_display_path (GimpImage *image);
void gimp_image_set_load_proc (GimpImage *image,
GimpPlugInProcedure *proc);
......
......@@ -36,9 +36,6 @@
#include "core/gimpimage.h"
#include "core/gimpitem.h"
#include "file/file-utils.h"
#include "file/gimp-file.h"
#include "gimpdisplay.h"
#include "gimpdisplayshell.h"
#include "gimpdisplayshell-title.h"
......@@ -57,11 +54,6 @@ static gint gimp_display_shell_format_title (GimpDisplayShell *display,
gchar *title,
gint title_len,
const gchar *format);
static gint gimp_display_shell_format_filename (gchar *buf,
gint len,
gint start,
GimpImage *image,
const gchar *filename);
/* public functions */
......@@ -211,24 +203,13 @@ gimp_display_shell_format_title (GimpDisplayShell *shell,
break;
case 'f': /* base filename */
{
const gchar *name = gimp_image_get_display_name (image);
i += gimp_display_shell_format_filename (title, title_len, i, image, name);
}
i += print (title, title_len, i, "%s",
gimp_image_get_display_name (image));
break;
case 'F': /* full filename */
{
gchar *filename;
const gchar *uri = gimp_image_get_uri_or_untitled (image);
filename = file_utils_uri_display_name (uri);
i += gimp_display_shell_format_filename (title, title_len, i, image, filename);
g_free (filename);
}
i += print (title, title_len, i, "%s",
gimp_image_get_display_path (image));
break;
case 'p': /* PDB id */
......@@ -451,69 +432,3 @@ gimp_display_shell_format_title (GimpDisplayShell *shell,
return i;
}
static gint
gimp_display_shell_format_filename (gchar *buf,
gint len,
gint start,
GimpImage *image,
const gchar *filename)
{
const gchar *source = NULL;
const gchar *name_format = NULL;
const gchar *export_status = NULL;
gchar *format_string = NULL;
gchar *name = NULL;
gboolean is_imported = FALSE;
gint incr = 0;
source = gimp_image_get_imported_uri (image);
/* Note that as soon as the image is saved, it is not considered
* imported any longer (gimp_image_set_imported_uri (image, NULL) is
* called)
*/
is_imported = (source != NULL);
/* Calculate filename and format */
if (! is_imported)
{
name = g_strdup (filename);
name_format = "%s";
}
else
{
gchar *source_no_ext = file_utils_uri_with_new_ext (source, NULL);
name = file_utils_uri_display_basename (source_no_ext);
g_free (source_no_ext);
name_format = "[%s]";
}
/* Calculate filename suffix */
if (! gimp_image_is_export_dirty (image))
{
gboolean is_exported;
is_exported = (gimp_image_get_exported_uri (image) != NULL);
if (is_exported)
export_status = _(" (exported)");
else if (is_imported)
export_status = _(" (overwritten)");
else
g_warning ("Unexpected code path, Save+export implementation is buggy!");
}
else if (is_imported)
{
export_status = _(" (imported)");
}
/* Merge strings and print the result */
format_string = g_strconcat (name_format, export_status, NULL);
incr = print (buf, len, start, format_string, name);
g_free (format_string);
/* Cleanup */
g_free (name);
return incr;
}
......@@ -436,7 +436,7 @@ file_open_with_proc_and_display (Gimp *gimp,
{
GimpDocumentList *documents = GIMP_DOCUMENT_LIST (gimp->documents);
GimpImagefile *imagefile;
const gchar *opened_uri;
const gchar *any_uri;
imagefile = gimp_document_list_add_uri (documents, uri, mime_type);
......@@ -444,9 +444,9 @@ file_open_with_proc_and_display (Gimp *gimp,
* resulting image's uri match. Use any_uri() here so we
* create thumbnails for both XCF and imported images.
*/
opened_uri = gimp_image_get_any_uri (image);
any_uri = gimp_image_get_any_uri (image);
if (opened_uri && ! strcmp (uri, opened_uri))
if (any_uri && ! strcmp (uri, any_uri))
{
/* no need to save a thumbnail if there's a good one already */
if (! gimp_imagefile_check_thumbnail (imagefile))
......
......@@ -178,6 +178,8 @@ file_save (Gimp *gimp,
* the export state to clean
*/
gimp_image_export_clean_all (image);
gimp_object_name_changed (GIMP_OBJECT (image));
}
else if (export_forward)
{
......
......@@ -53,6 +53,7 @@
#include "core/gimpprogress.h"
#include "core/gimpselection.h"
#include "core/gimpunit.h"
#include "file/file-utils.h"
#include "vectors/gimpvectors.h"
#include "gimppdb.h"
......@@ -2286,7 +2287,11 @@ image_get_name_invoker (GimpProcedure *procedure,
if (success)
{
name = g_strdup (gimp_image_get_display_name (image));
/* XXX do we really want to return this, or the name as in the title? */
const gchar *uri = gimp_image_get_uri_or_untitled (image);
name = file_utils_uri_display_basename (uri);
}
return_vals = gimp_procedure_get_return_values (procedure, success,
......
......@@ -2307,7 +2307,11 @@ HELP
%invoke = (
code => <<'CODE'
{
name = g_strdup (gimp_image_get_display_name (image));
/* XXX do we really want to return this, or the name as in the title? */
const gchar *uri = gimp_image_get_uri_or_untitled (image);
name = file_utils_uri_display_basename (uri);
}
CODE
);
......@@ -2896,6 +2900,7 @@ CODE
"core/gimpcontainer.h"
"core/gimpprogress.h"
"core/gimpunit.h"
"file/file-utils.h"
"gimppdbcontext.h"
"gimppdberror.h"
"gimppdb-utils.h"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment