1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995, 1996, 1997 Spencer Kimball and Peter Mattis
3  * Copyright (C) 1997 Josh MacDonald
4  *
5  * file-save.c
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  */
20 
21 #include "config.h"
22 
23 #include <gdk-pixbuf/gdk-pixbuf.h>
24 #include <gegl.h>
25 
26 #include "libgimpbase/gimpbase.h"
27 
28 #include "core/core-types.h"
29 
30 #include "config/gimpcoreconfig.h"
31 
32 #include "core/gimp.h"
33 #include "core/gimpcontext.h"
34 #include "core/gimpdocumentlist.h"
35 #include "core/gimpdrawable.h"
36 #include "core/gimpimage.h"
37 #include "core/gimpimagefile.h"
38 #include "core/gimpparamspecs.h"
39 #include "core/gimpprogress.h"
40 
41 #include "pdb/gimppdb.h"
42 
43 #include "plug-in/gimppluginprocedure.h"
44 
45 #include "file-remote.h"
46 #include "file-save.h"
47 #include "gimp-file.h"
48 
49 #include "gimp-intl.h"
50 
51 
52 /*  public functions  */
53 
54 GimpPDBStatusType
file_save(Gimp * gimp,GimpImage * image,GimpProgress * progress,GFile * file,GimpPlugInProcedure * file_proc,GimpRunMode run_mode,gboolean change_saved_state,gboolean export_backward,gboolean export_forward,GError ** error)55 file_save (Gimp                *gimp,
56            GimpImage           *image,
57            GimpProgress        *progress,
58            GFile               *file,
59            GimpPlugInProcedure *file_proc,
60            GimpRunMode          run_mode,
61            gboolean             change_saved_state,
62            gboolean             export_backward,
63            gboolean             export_forward,
64            GError             **error)
65 {
66   GimpDrawable      *drawable;
67   GimpValueArray    *return_vals;
68   GimpPDBStatusType  status     = GIMP_PDB_EXECUTION_ERROR;
69   GFile             *local_file = NULL;
70   gchar             *path       = NULL;
71   gchar             *uri        = NULL;
72   gboolean           mounted    = TRUE;
73   gint32             image_ID;
74   gint32             drawable_ID;
75   GError            *my_error   = NULL;
76 
77   g_return_val_if_fail (GIMP_IS_GIMP (gimp), GIMP_PDB_CALLING_ERROR);
78   g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_PDB_CALLING_ERROR);
79   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress),
80                         GIMP_PDB_CALLING_ERROR);
81   g_return_val_if_fail (G_IS_FILE (file), GIMP_PDB_CALLING_ERROR);
82   g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (file_proc),
83                         GIMP_PDB_CALLING_ERROR);
84   g_return_val_if_fail ((export_backward && export_forward) == FALSE,
85                         GIMP_PDB_CALLING_ERROR);
86   g_return_val_if_fail (error == NULL || *error == NULL,
87                         GIMP_PDB_CALLING_ERROR);
88 
89   /*  ref image and file, so they can't get deleted during save  */
90   g_object_ref (image);
91   g_object_ref (file);
92 
93   gimp_image_saving (image);
94 
95   drawable = gimp_image_get_active_drawable (image);
96 
97   if (! drawable)
98     {
99       g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
100                            _("There is no active layer to save"));
101       goto out;
102     }
103 
104   /* FIXME enable these tests for remote files again, needs testing */
105   if (g_file_is_native (file) &&
106       g_file_query_exists (file, NULL))
107     {
108       GFileInfo *info;
109 
110       info = g_file_query_info (file,
111                                 G_FILE_ATTRIBUTE_STANDARD_TYPE ","
112                                 G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
113                                 G_FILE_QUERY_INFO_NONE,
114                                 NULL, error);
115       if (! info)
116         {
117           /* extra paranoia */
118           if (error && ! *error)
119             g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
120                                  _("Failed to get file information"));
121           goto out;
122         }
123 
124       if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
125         {
126           g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
127                                _("Not a regular file"));
128           g_object_unref (info);
129           goto out;
130         }
131 
132       if (! g_file_info_get_attribute_boolean (info,
133                                                G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
134         {
135           g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
136                                _("Permission denied"));
137           g_object_unref (info);
138           goto out;
139         }
140 
141       g_object_unref (info);
142     }
143 
144   if (! g_file_is_native (file) &&
145       ! file_remote_mount_file (gimp, file, progress, &my_error))
146     {
147       if (my_error)
148         {
149           g_printerr ("%s: mounting remote volume failed, trying to upload"
150                       "the file: %s\n",
151                       G_STRFUNC, my_error->message);
152           g_clear_error (&my_error);
153 
154           mounted = FALSE;
155         }
156       else
157         {
158           status = GIMP_PDB_CANCEL;
159 
160           goto out;
161         }
162     }
163 
164   if (! file_proc->handles_uri || ! mounted)
165     {
166       gchar *my_path = g_file_get_path (file);
167 
168       if (! my_path)
169         {
170           local_file = file_remote_upload_image_prepare (gimp, file, progress,
171                                                          &my_error);
172 
173           if (! local_file)
174             {
175               if (my_error)
176                 g_propagate_error (error, my_error);
177               else
178                 status = GIMP_PDB_CANCEL;
179 
180               goto out;
181             }
182 
183           if (file_proc->handles_uri)
184             path = g_file_get_uri (local_file);
185           else
186             path = g_file_get_path (local_file);
187         }
188 
189       g_free (my_path);
190     }
191 
192   if (! path)
193     {
194       if (file_proc->handles_uri)
195         path = g_file_get_uri (file);
196       else
197         path = g_file_get_path (file);
198     }
199 
200   uri = g_file_get_uri (file);
201 
202   image_ID    = gimp_image_get_ID (image);
203   drawable_ID = gimp_item_get_ID (GIMP_ITEM (drawable));
204 
205   return_vals =
206     gimp_pdb_execute_procedure_by_name (image->gimp->pdb,
207                                         gimp_get_user_context (gimp),
208                                         progress, error,
209                                         gimp_object_get_name (file_proc),
210                                         GIMP_TYPE_INT32,       run_mode,
211                                         GIMP_TYPE_IMAGE_ID,    image_ID,
212                                         GIMP_TYPE_DRAWABLE_ID, drawable_ID,
213                                         G_TYPE_STRING,         path,
214                                         G_TYPE_STRING,         uri,
215                                         G_TYPE_NONE);
216 
217   status = g_value_get_enum (gimp_value_array_index (return_vals, 0));
218 
219   gimp_value_array_unref (return_vals);
220 
221   if (local_file)
222     {
223       if (status == GIMP_PDB_SUCCESS)
224         {
225           GError *my_error = NULL;
226 
227           if (! file_remote_upload_image_finish (gimp, file, local_file,
228                                                  progress, &my_error))
229             {
230               status = GIMP_PDB_EXECUTION_ERROR;
231 
232               if (my_error)
233                 g_propagate_error (error, my_error);
234               else
235                 status = GIMP_PDB_CANCEL;
236             }
237         }
238 
239       g_file_delete (local_file, NULL, NULL);
240       g_object_unref (local_file);
241     }
242 
243   if (status == GIMP_PDB_SUCCESS)
244     {
245       GimpDocumentList *documents;
246       GimpImagefile    *imagefile;
247 
248       if (change_saved_state)
249         {
250           gimp_image_set_file (image, file);
251           gimp_image_set_save_proc (image, file_proc);
252 
253           /* Forget the import source when we save. We interpret a
254            * save as that the user is not interested in being able
255            * to quickly export back to the original any longer
256            */
257           gimp_image_set_imported_file (image, NULL);
258 
259           gimp_image_clean_all (image);
260         }
261       else if (export_backward)
262         {
263           /* We exported the image back to its imported source,
264            * change nothing about export/import flags, only set
265            * the export state to clean
266            */
267           gimp_image_export_clean_all (image);
268         }
269       else if (export_forward)
270         {
271           /* Remember the last entered Export URI for the image. We
272            * only need to do this explicitly when exporting. It
273            * happens implicitly when saving since the GimpObject name
274            * of a GimpImage is the last-save URI
275            */
276           gimp_image_set_exported_file (image, file);
277           gimp_image_set_export_proc (image, file_proc);
278 
279           /* An image can not be considered both exported and imported
280            * at the same time, so stop consider it as imported now
281            * that we consider it exported.
282            */
283           gimp_image_set_imported_file (image, NULL);
284 
285           gimp_image_export_clean_all (image);
286         }
287 
288       if (export_backward || export_forward)
289         gimp_image_exported (image, file);
290       else
291         gimp_image_saved (image, file);
292 
293       documents = GIMP_DOCUMENT_LIST (image->gimp->documents);
294 
295       imagefile = gimp_document_list_add_file (documents, file,
296                                                g_slist_nth_data (file_proc->mime_types_list, 0));
297 
298       /* only save a thumbnail if we are saving as XCF, see bug #25272 */
299       if (GIMP_PROCEDURE (file_proc)->proc_type == GIMP_INTERNAL)
300         gimp_imagefile_save_thumbnail (imagefile,
301                                        g_slist_nth_data (file_proc->mime_types_list, 0),
302                                        image,
303                                        NULL);
304     }
305   else if (status != GIMP_PDB_CANCEL)
306     {
307       if (error && *error == NULL)
308         {
309           g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
310                        _("%s plug-in could not save image"),
311                        gimp_procedure_get_label (GIMP_PROCEDURE (file_proc)));
312         }
313     }
314 
315   gimp_image_flush (image);
316 
317  out:
318   g_object_unref (file);
319   g_object_unref (image);
320 
321   g_free (path);
322   g_free (uri);
323 
324   return status;
325 }
326