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