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 <string.h>
21
22 #include <gegl.h>
23 #include <gtk/gtk.h>
24
25 #include "libgimpbase/gimpbase.h"
26 #include "libgimpwidgets/gimpwidgets.h"
27
28 #include "dialogs-types.h"
29
30 #include "config/gimpguiconfig.h"
31
32 #include "core/gimp.h"
33 #include "core/gimpcontext.h"
34 #include "core/gimpimage.h"
35 #include "core/gimpimage-scale.h"
36
37 #include "widgets/gimphelp-ids.h"
38 #include "widgets/gimpmessagebox.h"
39 #include "widgets/gimpmessagedialog.h"
40
41 #include "scale-dialog.h"
42
43 #include "image-scale-dialog.h"
44
45 #include "gimp-intl.h"
46
47
48 typedef struct
49 {
50 GtkWidget *dialog;
51
52 GimpImage *image;
53
54 gint width;
55 gint height;
56 GimpUnit unit;
57 GimpInterpolationType interpolation;
58 gdouble xresolution;
59 gdouble yresolution;
60 GimpUnit resolution_unit;
61
62 GimpScaleCallback callback;
63 gpointer user_data;
64 } ImageScaleDialog;
65
66
67 /* local function prototypes */
68
69 static void image_scale_dialog_free (ImageScaleDialog *private);
70 static void image_scale_callback (GtkWidget *widget,
71 GimpViewable *viewable,
72 gint width,
73 gint height,
74 GimpUnit unit,
75 GimpInterpolationType interpolation,
76 gdouble xresolution,
77 gdouble yresolution,
78 GimpUnit resolution_unit,
79 gpointer data);
80
81 static GtkWidget * image_scale_confirm_dialog (ImageScaleDialog *private);
82 static void image_scale_confirm_large (ImageScaleDialog *private,
83 gint64 new_memsize,
84 gint64 max_memsize);
85 static void image_scale_confirm_small (ImageScaleDialog *private);
86 static void image_scale_confirm_response (GtkWidget *widget,
87 gint response_id,
88 ImageScaleDialog *private);
89
90
91 /* public functions */
92
93 GtkWidget *
image_scale_dialog_new(GimpImage * image,GimpContext * context,GtkWidget * parent,GimpUnit unit,GimpInterpolationType interpolation,GimpScaleCallback callback,gpointer user_data)94 image_scale_dialog_new (GimpImage *image,
95 GimpContext *context,
96 GtkWidget *parent,
97 GimpUnit unit,
98 GimpInterpolationType interpolation,
99 GimpScaleCallback callback,
100 gpointer user_data)
101 {
102 ImageScaleDialog *private;
103
104 g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
105 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
106 g_return_val_if_fail (callback != NULL, NULL);
107
108 private = g_slice_new0 (ImageScaleDialog);
109
110 private->image = image;
111 private->callback = callback;
112 private->user_data = user_data;
113
114 private->dialog = scale_dialog_new (GIMP_VIEWABLE (image), context,
115 C_("dialog-title", "Scale Image"),
116 "gimp-image-scale",
117 parent,
118 gimp_standard_help_func,
119 GIMP_HELP_IMAGE_SCALE,
120 unit,
121 interpolation,
122 image_scale_callback,
123 private);
124
125 g_object_weak_ref (G_OBJECT (private->dialog),
126 (GWeakNotify) image_scale_dialog_free, private);
127
128 return private->dialog;
129 }
130
131
132 /* private functions */
133
134 static void
image_scale_dialog_free(ImageScaleDialog * private)135 image_scale_dialog_free (ImageScaleDialog *private)
136 {
137 g_slice_free (ImageScaleDialog, private);
138 }
139
140 static void
image_scale_callback(GtkWidget * widget,GimpViewable * viewable,gint width,gint height,GimpUnit unit,GimpInterpolationType interpolation,gdouble xresolution,gdouble yresolution,GimpUnit resolution_unit,gpointer data)141 image_scale_callback (GtkWidget *widget,
142 GimpViewable *viewable,
143 gint width,
144 gint height,
145 GimpUnit unit,
146 GimpInterpolationType interpolation,
147 gdouble xresolution,
148 gdouble yresolution,
149 GimpUnit resolution_unit,
150 gpointer data)
151 {
152 ImageScaleDialog *private = data;
153 GimpImage *image = GIMP_IMAGE (viewable);
154 GimpImageScaleCheckType scale_check;
155 gint64 max_memsize;
156 gint64 new_memsize;
157
158 private->width = width;
159 private->height = height;
160 private->unit = unit;
161 private->interpolation = interpolation;
162 private->xresolution = xresolution;
163 private->yresolution = yresolution;
164 private->resolution_unit = resolution_unit;
165
166 gtk_widget_set_sensitive (widget, FALSE);
167
168 max_memsize = GIMP_GUI_CONFIG (image->gimp->config)->max_new_image_size;
169
170 scale_check = gimp_image_scale_check (image,
171 width, height, max_memsize,
172 &new_memsize);
173 switch (scale_check)
174 {
175 case GIMP_IMAGE_SCALE_TOO_BIG:
176 image_scale_confirm_large (private, new_memsize, max_memsize);
177 break;
178
179 case GIMP_IMAGE_SCALE_TOO_SMALL:
180 image_scale_confirm_small (private);
181 break;
182
183 case GIMP_IMAGE_SCALE_OK:
184 private->callback (private->dialog,
185 GIMP_VIEWABLE (private->image),
186 private->width,
187 private->height,
188 private->unit,
189 private->interpolation,
190 private->xresolution,
191 private->yresolution,
192 private->resolution_unit,
193 private->user_data);
194 break;
195 }
196 }
197
198 static GtkWidget *
image_scale_confirm_dialog(ImageScaleDialog * private)199 image_scale_confirm_dialog (ImageScaleDialog *private)
200 {
201 GtkWidget *widget;
202
203 widget = gimp_message_dialog_new (_("Confirm Scaling"),
204 GIMP_ICON_DIALOG_WARNING,
205 private->dialog,
206 GTK_DIALOG_DESTROY_WITH_PARENT,
207 gimp_standard_help_func,
208 GIMP_HELP_IMAGE_SCALE_WARNING,
209
210 _("_Cancel"), GTK_RESPONSE_CANCEL,
211 _("_Scale"), GTK_RESPONSE_OK,
212
213 NULL);
214
215 gtk_dialog_set_alternative_button_order (GTK_DIALOG (widget),
216 GTK_RESPONSE_OK,
217 GTK_RESPONSE_CANCEL,
218 -1);
219
220 g_signal_connect (widget, "response",
221 G_CALLBACK (image_scale_confirm_response),
222 private);
223
224 return widget;
225 }
226
227 static void
image_scale_confirm_large(ImageScaleDialog * private,gint64 new_memsize,gint64 max_memsize)228 image_scale_confirm_large (ImageScaleDialog *private,
229 gint64 new_memsize,
230 gint64 max_memsize)
231 {
232 GtkWidget *widget = image_scale_confirm_dialog (private);
233 gchar *size;
234
235 size = g_format_size (new_memsize);
236 gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (widget)->box,
237 _("You are trying to create an image "
238 "with a size of %s."), size);
239 g_free (size);
240
241 size = g_format_size (max_memsize);
242 gimp_message_box_set_text (GIMP_MESSAGE_DIALOG (widget)->box,
243 _("Scaling the image to the chosen size will "
244 "make it use more memory than what is "
245 "configured as \"Maximum Image Size\" in the "
246 "Preferences dialog (currently %s)."), size);
247 g_free (size);
248
249 gtk_widget_show (widget);
250 }
251
252 static void
image_scale_confirm_small(ImageScaleDialog * private)253 image_scale_confirm_small (ImageScaleDialog *private)
254 {
255 GtkWidget *widget = image_scale_confirm_dialog (private);
256
257 gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (widget)->box,
258 _("Scaling the image to the chosen size "
259 "will shrink some layers completely "
260 "away."));
261 gimp_message_box_set_text (GIMP_MESSAGE_DIALOG (widget)->box,
262 _("Is this what you want to do?"));
263
264 gtk_widget_show (widget);
265 }
266
267 static void
image_scale_confirm_response(GtkWidget * widget,gint response_id,ImageScaleDialog * private)268 image_scale_confirm_response (GtkWidget *widget,
269 gint response_id,
270 ImageScaleDialog *private)
271 {
272 gtk_widget_destroy (widget);
273
274 if (response_id == GTK_RESPONSE_OK)
275 {
276 private->callback (private->dialog,
277 GIMP_VIEWABLE (private->image),
278 private->width,
279 private->height,
280 private->unit,
281 private->interpolation,
282 private->xresolution,
283 private->yresolution,
284 private->resolution_unit,
285 private->user_data);
286 }
287 else
288 {
289 gtk_widget_set_sensitive (private->dialog, TRUE);
290 }
291 }
292