Adapted to new eog_image_save signature.

2003-12-21  Jens Finke  <jens@triq.net>

	* collection/eog-collection-view.c (save_image_loading_finished):
	Adapted to new eog_image_save signature.

	* libeog/eog-file-selection.[ch] (eog_file_selection_add_filter):
	Attach GdkPixbufFormat to filter for further reference.
	(eog_file_selection_get_format): New function.

	* libeog/eog-image-jpeg.[ch] (get_tmp_filepath),
	(move_file_to_uri): New functions.
	(eog_image_jpeg_save),
	(eog_image_jpeg_save_lossless): Dump data to temporary file first
	and move it to final destination afterwards.

	* libeog/eog-image.[ch] (real_image_load): Set image status to failed
	if we read 0 bytes.
	(eog_image_save): Added GdkPixbufFormat parameter, better
	retrieving of target filetype.

	* viewer/eog-image-view.c (verb_SaveAs_cb): Get image format from
	file chooser.
	(save_uri): New function, which takes an additional
	GdkPixbufFormat parameter.
This commit is contained in:
Jens Finke 2003-12-21 10:35:11 +00:00 committed by Jens Finke
parent 069c641c31
commit 7096d37abd
9 changed files with 186 additions and 34 deletions

View file

@ -1,3 +1,28 @@
2003-12-21 Jens Finke <jens@triq.net>
* collection/eog-collection-view.c (save_image_loading_finished):
Adapted to new eog_image_save signature.
* libeog/eog-file-selection.[ch] (eog_file_selection_add_filter):
Attach GdkPixbufFormat to filter for further reference.
(eog_file_selection_get_format): New function.
* libeog/eog-image-jpeg.[ch] (get_tmp_filepath),
(move_file_to_uri): New functions.
(eog_image_jpeg_save),
(eog_image_jpeg_save_lossless): Dump data to temporary file first
and move it to final destination afterwards.
* libeog/eog-image.[ch] (real_image_load): Set image status to failed
if we read 0 bytes.
(eog_image_save): Added GdkPixbufFormat parameter, better
retrieving of target filetype.
* viewer/eog-image-view.c (verb_SaveAs_cb): Get image format from
file chooser.
(save_uri): New function, which takes an additional
GdkPixbufFormat parameter.
2003-12-19 Jens Finke <jens@triq.net>
* libeog/eog-image.c (eog_image_save): Update URI and clear

View file

@ -312,7 +312,7 @@ save_image_loading_finished (EogImage *image, gpointer data)
uri = eog_image_get_uri (image);
if (!eog_image_save (image, uri, &error)) {
if (!eog_image_save (image, uri, NULL, &error)) {
/* FIXME: indicate failed state to the user */
}
gnome_vfs_uri_unref (uri);

View file

@ -10,12 +10,13 @@
#include <gtk/gtkhbox.h>
#include <gtk/gtkstock.h>
#include <gtk/gtkmessagedialog.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "eog-hig-dialog.h"
#include "eog-pixbuf-util.h"
static char* last_dir[] = { NULL, NULL };
#define FILE_FORMAT_KEY "file-format"
GNOME_CLASS_BOILERPLATE (EogFileSelection,
eog_file_selection,
GtkFileChooserDialog,
@ -137,7 +138,7 @@ eog_file_selection_add_filter (GtkWidget *widget)
gdk_pixbuf_format_get_name (format));
gtk_file_filter_set_name (filter, filter_name);
g_free (filter_name);
mime_types = gdk_pixbuf_format_get_mime_types ((GdkPixbufFormat *) it->data);
for (i = 0; mime_types[i] != NULL; i++) {
gtk_file_filter_add_mime_type (filter, mime_types[i]);
@ -154,6 +155,12 @@ eog_file_selection_add_filter (GtkWidget *widget)
}
g_strfreev (pattern);
/* attach GdkPixbufFormat to filter, see also
* eog_file_selection_get_format. */
g_object_set_data (G_OBJECT (filter),
FILE_FORMAT_KEY,
format);
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filesel), filter);
}
@ -233,3 +240,19 @@ eog_folder_selection_new (void)
return filesel;
}
GdkPixbufFormat*
eog_file_selection_get_format (EogFileSelection *sel)
{
GtkFileFilter *filter;
GdkPixbufFormat* format;
g_return_val_if_fail (EOG_IS_FILE_SELECTION (sel), NULL);
filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (sel));
if (filter == NULL) return NULL;
format = g_object_get_data (G_OBJECT (filter), FILE_FORMAT_KEY);
return format;
}

View file

@ -2,6 +2,7 @@
#define _EOG_FILE_SELECTION_H_
#include <gtk/gtkfilechooserdialog.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
G_BEGIN_DECLS
@ -32,6 +33,8 @@ GtkWidget* eog_file_selection_new (GtkFileChooserAction action);
GtkWidget* eog_folder_selection_new (void);
GdkPixbufFormat* eog_file_selection_get_format (EogFileSelection *sel);
G_END_DECLS
#endif /* _EOG_FILE_SELECTION_H_ */

View file

@ -32,6 +32,8 @@
#if HAVE_JPEG
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -46,11 +48,51 @@
#endif
#include "eog-image-private.h"
static char*
get_tmp_filepath (void)
{
char *tmp_file;
char *tmp_file_name;
static int file_count = 0;
tmp_file_name = g_strdup_printf ("eog%i%i.tmp", getpid (), file_count++);
tmp_file = g_build_filename (g_get_tmp_dir (), tmp_file_name, NULL);
g_free (tmp_file_name);
return tmp_file;
}
static GnomeVFSResult
move_file_to_uri (char *file_path, GnomeVFSURI *uri)
{
GnomeVFSResult result;
GnomeVFSURI *source_uri;
source_uri = gnome_vfs_uri_new (file_path);
result = gnome_vfs_xfer_uri (source_uri,
uri,
GNOME_VFS_XFER_DELETE_ITEMS, /* delete source file */
GNOME_VFS_XFER_ERROR_MODE_ABORT, /* abort on all errors */
GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, /* we checked for existing
file already */
NULL, /* no progress callback */
NULL);
gnome_vfs_uri_unref (source_uri);
return result;
}
gboolean
eog_image_jpeg_save (EogImage *image, const char *path, GError **error)
eog_image_jpeg_save (EogImage *image, GnomeVFSURI *uri, GError **error)
{
EogImagePrivate *priv;
GdkPixbuf *pixbuf;
GnomeVFSResult vfs_result;
char *tmp_path;
struct jpeg_compress_struct cinfo;
guchar *buf = NULL;
guchar *ptr;
@ -76,8 +118,9 @@ eog_image_jpeg_save (EogImage *image, const char *path, GError **error)
if (pixbuf == NULL) {
return FALSE;
}
outfile = fopen (path, "wb");
tmp_path = get_tmp_filepath ();
outfile = fopen (tmp_path, "wb");
if (outfile == NULL) {
return FALSE;
}
@ -151,19 +194,30 @@ eog_image_jpeg_save (EogImage *image, const char *path, GError **error)
fclose (outfile);
return TRUE;
/* move temporary file to final destination */
vfs_result = move_file_to_uri (tmp_path, uri);
if (vfs_result != GNOME_VFS_OK) {
g_set_error (error, EOG_IMAGE_ERROR,
EOG_IMAGE_ERROR_VFS,
gnome_vfs_result_to_string (vfs_result));
}
g_free (tmp_path);
return (vfs_result == GNOME_VFS_OK);
}
gboolean
eog_image_jpeg_save_lossless (EogImage *image, const char *path, GError **error)
eog_image_jpeg_save_lossless (EogImage *image, GnomeVFSURI *uri, GError **error)
{
const char *img_path;
int result;
JXFORM_CODE trans_code = JXFORM_NONE;
EogTransformType transformation;
char *tmp_file;
GnomeVFSResult vfs_result = GNOME_VFS_OK;
g_return_val_if_fail (EOG_IS_IMAGE (image), FALSE);
g_return_val_if_fail (path != NULL, FALSE);
g_return_val_if_fail (uri != NULL, FALSE);
img_path = gnome_vfs_uri_get_path (image->priv->uri);
@ -191,9 +245,32 @@ eog_image_jpeg_save_lossless (EogImage *image, const char *path, GError **error)
}
}
result = jpegtran ((char*) img_path, (char*) path, trans_code, error);
/* We save the resulting jpeg file to a temporary location
* first and move it to the final destination then. This way
* can also overwrite a file.
*/
tmp_file = get_tmp_filepath ();
g_print ("tmp_file: %s\n", tmp_file);
return (result == 0);
result = jpegtran ((char*) img_path, (char*) tmp_file, trans_code, error);
if (result == 0) {
/* image successfully written */
vfs_result = move_file_to_uri (tmp_file, uri);
if (vfs_result != GNOME_VFS_OK) {
g_set_error (error, EOG_IMAGE_ERROR,
EOG_IMAGE_ERROR_VFS,
gnome_vfs_result_to_string (vfs_result));
}
}
if (g_file_test (tmp_file, G_FILE_TEST_EXISTS)) {
gnome_vfs_unlink (tmp_file);
}
g_free (tmp_file);
return ((result == 0) && (vfs_result == GNOME_VFS_OK));
}
#endif

View file

@ -6,15 +6,16 @@
#if HAVE_JPEG
#include <glib.h>
#include <libgnomevfs/gnome-vfs.h>
#include "eog-image.h"
/* This will include some specialized routines for JPEG images, to support
saving and transformations better for this format. */
gboolean eog_image_jpeg_save (EogImage *image, const char *path, GError **error);
gboolean eog_image_jpeg_save (EogImage *image, GnomeVFSURI *uri, GError **error);
/* This assumes that image represents a jpeg file on the local filesystem! */
gboolean eog_image_jpeg_save_lossless (EogImage *image, const char *path, GError **error);
gboolean eog_image_jpeg_save_lossless (EogImage *image, GnomeVFSURI *uri, GError **error);
#endif

View file

@ -843,7 +843,7 @@ real_image_load (gpointer data)
gnome_vfs_close (handle);
gnome_vfs_file_info_unref (info);
if (failed) {
if (failed || (bytes_read_total == 0)) {
g_mutex_lock (priv->status_mutex);
if (priv->image != NULL) {
g_object_unref (priv->image);
@ -855,6 +855,9 @@ real_image_load (gpointer data)
if (error != NULL) {
priv->error_message = g_strdup (error->message);
}
else if (bytes_read_total == 0) {
priv->error_message = g_strdup (_("empty file"));
}
else {
priv->error_message = NULL;
}
@ -1274,7 +1277,7 @@ get_save_file_type_by_suffix (const char *local_path)
}
gboolean
eog_image_save (EogImage *img, GnomeVFSURI *uri, GError **error)
eog_image_save (EogImage *img, GnomeVFSURI *uri, GdkPixbufFormat *format, GError **error)
{
EogImagePrivate *priv;
char *file;
@ -1306,11 +1309,25 @@ eog_image_save (EogImage *img, GnomeVFSURI *uri, GError **error)
_("Images can only be saved as local files."));
return FALSE;
}
/* find file type for saving, according to filename suffix */
file = (char*) gnome_vfs_uri_get_path (uri); /* don't free file, it's a static string */
target_type = get_save_file_type_by_suffix (file);
/* determine type of file to write (eg. 'png') */
if (format == NULL) {
if (gnome_vfs_uri_equal (priv->uri, uri)) {
/* we overwrite the same file, therefore we
* can reuse the file type saved in the EogImage object. */
target_type = g_strdup (priv->file_type);
}
else {
/* find file type for saving, according to filename suffix */
target_type = get_save_file_type_by_suffix (file);
}
}
else {
target_type = gdk_pixbuf_format_get_name (format);
}
if (target_type == NULL) {
g_set_error (error, GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
@ -1321,8 +1338,8 @@ eog_image_save (EogImage *img, GnomeVFSURI *uri, GError **error)
source_is_local = (priv->uri != NULL && is_local_uri (priv->uri));
source_type = priv->file_type;
/* Check for some special cases, so that we use always the least intrusive method
* for saving the image.
/* Check for some special cases, so that we use always the
* least intrusive method for saving the image.
*/
if ((g_ascii_strcasecmp (target_type, source_type) == 0) &&
!eog_image_is_modified (img))
@ -1334,11 +1351,11 @@ eog_image_save (EogImage *img, GnomeVFSURI *uri, GError **error)
vfs_result = gnome_vfs_xfer_uri (priv->uri,
uri,
GNOME_VFS_XFER_DEFAULT /* copy the data */,
GNOME_VFS_XFER_ERROR_MODE_ABORT, /* abort on all errors */
GNOME_VFS_XFER_DEFAULT /* copy the data */,
GNOME_VFS_XFER_ERROR_MODE_ABORT, /* abort on all errors */
GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, /* we checked for existing
file already */
NULL, /* no progress callback */
NULL, /* no progress callback */
NULL);
result = (vfs_result == GNOME_VFS_OK);
if (!result) {
@ -1356,7 +1373,7 @@ eog_image_save (EogImage *img, GnomeVFSURI *uri, GError **error)
/* If source is a local file and both are jpeg files,
* then use lossless transformation through libjpeg.
*/
result = eog_image_jpeg_save_lossless (img, file, error);
result = eog_image_jpeg_save_lossless (img, uri, error);
g_print ("loseless saving of %s to %s\n",
gnome_vfs_uri_to_string (priv->uri, GNOME_VFS_URI_HIDE_NONE), file);
@ -1368,7 +1385,7 @@ eog_image_save (EogImage *img, GnomeVFSURI *uri, GError **error)
* libjpeg.
*/
g_print ("Save through jpeg library.\n");
result = eog_image_jpeg_save (img, file, error);
result = eog_image_jpeg_save (img, uri, error);
}
#endif
#endif

View file

@ -75,6 +75,7 @@ gboolean eog_image_is_loaded (EogImage *img);
/* saving API */
gboolean eog_image_save (EogImage *img,
GnomeVFSURI *uri,
GdkPixbufFormat *format,
GError **error);
/* query API */

View file

@ -117,6 +117,7 @@ enum {
static void popup_menu_cb (gpointer data, guint action, GtkWidget *widget);
static gint save_uri_cb (BonoboPersistFile *pf, const CORBA_char *text_uri,
CORBA_Environment *ev, void *closure);
static gboolean save_uri (EogImageView *view, const char *text_uri, GdkPixbufFormat *format);
static guint signals[LAST_SIGNAL] = { 0 };
@ -316,6 +317,7 @@ verb_SaveAs_cb (BonoboUIComponent *uic, gpointer user_data,
GtkWidget *dlg;
int response;
gchar *filename = NULL;
GdkPixbufFormat *format = NULL;
g_return_if_fail (EOG_IS_IMAGE_VIEW (user_data));
@ -330,14 +332,13 @@ verb_SaveAs_cb (BonoboUIComponent *uic, gpointer user_data,
if (response == GTK_RESPONSE_OK) {
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
format = eog_file_selection_get_format (EOG_FILE_SELECTION (dlg));
}
gtk_widget_destroy (dlg);
if (response == GTK_RESPONSE_OK) {
save_uri_cb (NULL, filename, NULL, image_view);
save_uri (image_view, filename, format);
}
if (filename != NULL) {
@ -1102,22 +1103,26 @@ static gint
save_uri_cb (BonoboPersistFile *pf, const CORBA_char *text_uri,
CORBA_Environment *ev, void *closure)
{
EogImageView *view;
return save_uri (EOG_IMAGE_VIEW (closure), text_uri, NULL);
}
static gboolean
save_uri (EogImageView *view, const char *text_uri, GdkPixbufFormat *format)
{
GnomeVFSURI *uri;
GError *error = NULL;
GtkWidget *dialog;
gboolean result;
g_return_val_if_fail (EOG_IS_IMAGE_VIEW (closure), 1);
g_return_val_if_fail (text_uri != NULL, 1);
g_return_val_if_fail (EOG_IS_IMAGE_VIEW (view), FALSE);
g_return_val_if_fail (text_uri != NULL, FALSE);
view = EOG_IMAGE_VIEW (closure);
if (view->priv->image == NULL) return FALSE;
/* FIXME: what kind of escaping do we need here? */
uri = gnome_vfs_uri_new (text_uri);
result = eog_image_save (view->priv->image, uri, &error);
result = eog_image_save (view->priv->image, uri, format, &error);
if (result) {
dialog = eog_hig_dialog_new (GTK_STOCK_DIALOG_INFO,