1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include <libgimp/gimp.h>
21 #include <libgimp/gimpui.h>
22
23 #include "print.h"
24 #include "print-settings.h"
25 #include "print-utils.h"
26
27
28 #define PRINT_SETTINGS_MAJOR_VERSION 0
29 #define PRINT_SETTINGS_MINOR_VERSION 4
30
31 #define PRINT_SETTINGS_NAME "print-settings"
32
33
34 static GKeyFile * print_settings_key_file_from_settings (PrintData *data);
35
36 static void print_settings_add_to_key_file (const gchar *key,
37 const gchar *value,
38 gpointer data);
39
40 static GKeyFile * print_settings_key_file_from_resource_file (void);
41
42 static GKeyFile * print_settings_key_file_from_parasite (gint32 image_ID);
43
44 static gboolean print_settings_load_from_key_file (PrintData *data,
45 GKeyFile *key_file);
46
47 static gboolean print_settings_check_version (GKeyFile *key_file);
48
49 /*
50 * set GtkPrintSettings from the contents of a "print-settings"
51 * image parasite, or, if none exists, from a resource
52 * file of the same name
53 */
54 gboolean
print_settings_load(PrintData * data)55 print_settings_load (PrintData *data)
56 {
57 GKeyFile *key_file = print_settings_key_file_from_parasite (data->image_id);
58
59 if (! key_file)
60 key_file = print_settings_key_file_from_resource_file ();
61
62 if (key_file)
63 {
64 print_settings_load_from_key_file (data, key_file);
65 g_key_file_free (key_file);
66 return TRUE;
67 }
68
69 return FALSE;
70 }
71
72 /*
73 * save all settings as a resource file "print-settings"
74 * and as an image parasite
75 */
76 void
print_settings_save(PrintData * data)77 print_settings_save (PrintData *data)
78 {
79 GKeyFile *key_file = print_settings_key_file_from_settings (data);
80
81 /* image setup */
82 if (gimp_image_is_valid (data->image_id))
83 {
84 gdouble xres;
85 gdouble yres;
86
87 gimp_image_get_resolution (data->image_id, &xres, &yres);
88
89 g_key_file_set_integer (key_file, "image-setup",
90 "unit", data->unit);
91 /* Do not save the print resolution when it is the expected image
92 * resolution so that changing it (i.e. in "print size" dialog)
93 * is not overridden by any previous prints.
94 */
95 if ((data->min_xres <= xres && ABS (xres - data->xres) > 0.1) ||
96 (data->min_yres <= yres && ABS (yres - data->yres) > 0.1) ||
97 (data->min_xres > xres && ABS (data->min_xres - data->xres) > 0.1) ||
98 (data->min_yres > yres && ABS (data->min_yres - data->yres) > 0.1))
99 {
100 g_key_file_set_double (key_file, "image-setup",
101 "x-resolution", data->xres);
102 g_key_file_set_double (key_file, "image-setup",
103 "y-resolution", data->yres);
104 }
105 g_key_file_set_double (key_file, "image-setup",
106 "x-offset", data->offset_x);
107 g_key_file_set_double (key_file, "image-setup",
108 "y-offset", data->offset_y);
109 g_key_file_set_integer (key_file, "image-setup",
110 "center-mode", data->center);
111 g_key_file_set_boolean (key_file, "image-setup",
112 "use-full-page", data->use_full_page);
113 g_key_file_set_boolean (key_file, "image-setup",
114 "crop-marks", data->draw_crop_marks);
115
116 print_utils_key_file_save_as_parasite (key_file,
117 data->image_id,
118 PRINT_SETTINGS_NAME);
119 }
120
121 /* some settings shouldn't be made persistent on a global level,
122 * so they are only stored in the image, not in the rcfile
123 */
124
125 g_key_file_remove_key (key_file, "image-setup", "x-resolution", NULL);
126 g_key_file_remove_key (key_file, "image-setup", "y-resolution", NULL);
127 g_key_file_remove_key (key_file, "image-setup", "x-offset", NULL);
128 g_key_file_remove_key (key_file, "image-setup", "y-offset", NULL);
129
130 g_key_file_remove_key (key_file, PRINT_SETTINGS_NAME, "n-copies", NULL);
131
132 print_utils_key_file_save_as_rcfile (key_file, PRINT_SETTINGS_NAME);
133
134 g_key_file_free (key_file);
135 }
136
137 /*
138 * serialize print settings into a GKeyFile
139 */
140 static GKeyFile *
print_settings_key_file_from_settings(PrintData * data)141 print_settings_key_file_from_settings (PrintData *data)
142 {
143 GtkPrintOperation *operation = data->operation;
144 GtkPrintSettings *settings;
145 GKeyFile *key_file = g_key_file_new ();
146
147 /* put version information into the file */
148 g_key_file_set_integer (key_file, "meta", "major-version",
149 PRINT_SETTINGS_MAJOR_VERSION);
150 g_key_file_set_integer (key_file, "meta", "minor-version",
151 PRINT_SETTINGS_MINOR_VERSION);
152
153 /* save the contents of the GtkPrintSettings for the operation */
154 settings = gtk_print_operation_get_print_settings (operation);
155
156 if (settings)
157 gtk_print_settings_foreach (settings,
158 print_settings_add_to_key_file, key_file);
159
160 return key_file;
161 }
162
163 /*
164 * callback used in gtk_print_settings_foreach loop
165 */
166 static void
print_settings_add_to_key_file(const gchar * key,const gchar * value,gpointer data)167 print_settings_add_to_key_file (const gchar *key,
168 const gchar *value,
169 gpointer data)
170 {
171 GKeyFile *key_file = data;
172
173 g_key_file_set_value (key_file, PRINT_SETTINGS_NAME, key, value);
174 }
175
176 /*
177 * deserialize a "print-settings" resource file into a GKeyFile
178 */
179 static GKeyFile *
print_settings_key_file_from_resource_file(void)180 print_settings_key_file_from_resource_file (void)
181 {
182 GKeyFile *key_file;
183
184 key_file = print_utils_key_file_load_from_rcfile (PRINT_SETTINGS_NAME);
185
186 if (key_file && ! print_settings_check_version (key_file))
187 {
188 g_key_file_free (key_file);
189 return NULL;
190 }
191
192 return key_file;
193 }
194
195 /* load information from an image parasite called "print-settings"
196 * return a GKeyFile containing the information if a valid parasite is found,
197 * NULL otherwise
198 */
199 static GKeyFile *
print_settings_key_file_from_parasite(gint32 image_ID)200 print_settings_key_file_from_parasite (gint32 image_ID)
201 {
202 GKeyFile *key_file;
203
204 key_file = print_utils_key_file_load_from_parasite (image_ID,
205 PRINT_SETTINGS_NAME);
206
207 if (key_file && ! print_settings_check_version (key_file))
208 {
209 g_key_file_free (key_file);
210 return NULL;
211 }
212
213 return key_file;
214 }
215
216 static gboolean
print_settings_load_from_key_file(PrintData * data,GKeyFile * key_file)217 print_settings_load_from_key_file (PrintData *data,
218 GKeyFile *key_file)
219 {
220 GtkPrintOperation *operation = data->operation;
221 GtkPrintSettings *settings;
222 gchar **keys;
223 gsize n_keys;
224 gint i;
225
226 settings = gtk_print_operation_get_print_settings (operation);
227 if (! settings)
228 settings = gtk_print_settings_new ();
229
230 keys = g_key_file_get_keys (key_file, PRINT_SETTINGS_NAME, &n_keys, NULL);
231
232 if (! keys)
233 return FALSE;
234
235 for (i = 0; i < n_keys; i++)
236 {
237 gchar *value;
238
239 value = g_key_file_get_value (key_file,
240 PRINT_SETTINGS_NAME, keys[i], NULL);
241
242 if (value)
243 {
244 gtk_print_settings_set (settings, keys[i], value);
245 g_free (value);
246 }
247 }
248
249 g_strfreev (keys);
250
251 if (g_key_file_has_key (key_file, "image-setup", "unit", NULL))
252 {
253 data->unit = g_key_file_get_integer (key_file, "image-setup",
254 "unit", NULL);
255 }
256
257 if (g_key_file_has_key (key_file, "image-setup", "x-resolution", NULL) &&
258 g_key_file_has_key (key_file, "image-setup", "y-resolution", NULL))
259 {
260 data->xres = g_key_file_get_double (key_file, "image-setup",
261 "x-resolution", NULL);
262 data->yres = g_key_file_get_double (key_file, "image-setup",
263 "y-resolution", NULL);
264 }
265
266 if (g_key_file_has_key (key_file, "image-setup", "x-offset", NULL) &&
267 g_key_file_has_key (key_file, "image-setup", "y-offset", NULL))
268 {
269 data->offset_x = g_key_file_get_double (key_file, "image-setup",
270 "x-offset", NULL);
271 data->offset_y = g_key_file_get_double (key_file, "image-setup",
272 "y-offset", NULL);
273 }
274
275 if (g_key_file_has_key (key_file, "image-setup", "center-mode", NULL))
276 {
277 data->center = g_key_file_get_integer (key_file, "image-setup",
278 "center-mode", NULL);
279 }
280
281 if (g_key_file_has_key (key_file, "image-setup", "use-full-page", NULL))
282 {
283 data->use_full_page = g_key_file_get_boolean (key_file, "image-setup",
284 "use-full-page", NULL);
285 }
286
287 if (g_key_file_has_key (key_file, "image-setup", "crop-marks", NULL))
288 {
289 data->draw_crop_marks = g_key_file_get_boolean (key_file, "image-setup",
290 "crop-marks", NULL);
291 }
292
293 gtk_print_operation_set_print_settings (operation, settings);
294
295 return TRUE;
296 }
297
298 static gboolean
print_settings_check_version(GKeyFile * key_file)299 print_settings_check_version (GKeyFile *key_file)
300 {
301 gint major_version;
302 gint minor_version;
303
304 if (! g_key_file_has_group (key_file, "meta"))
305 return FALSE;
306
307 major_version = g_key_file_get_integer (key_file,
308 "meta", "major-version", NULL);
309
310 if (major_version != PRINT_SETTINGS_MAJOR_VERSION)
311 return FALSE;
312
313 minor_version = g_key_file_get_integer (key_file,
314 "meta", "minor-version", NULL);
315
316 if (minor_version != PRINT_SETTINGS_MINOR_VERSION)
317 return FALSE;
318
319 return TRUE;
320 }
321