1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * gimpprogress.c
5 * Copyright (C) 2004 Michael Natterer <mitch@gimp.org>
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 <string.h>
24
25 #include <gio/gio.h>
26 #include <gegl.h>
27
28 #include "core-types.h"
29
30 #include "gimp.h"
31 #include "gimpmarshal.h"
32 #include "gimpprogress.h"
33
34 #include "gimp-intl.h"
35
36
37 enum
38 {
39 CANCEL,
40 LAST_SIGNAL
41 };
42
43
44 G_DEFINE_INTERFACE (GimpProgress, gimp_progress, G_TYPE_OBJECT)
45
46
47 static guint progress_signals[LAST_SIGNAL] = { 0 };
48
49
50 /* private functions */
51
52
53 static void
gimp_progress_default_init(GimpProgressInterface * progress_iface)54 gimp_progress_default_init (GimpProgressInterface *progress_iface)
55 {
56 progress_signals[CANCEL] =
57 g_signal_new ("cancel",
58 G_TYPE_FROM_INTERFACE (progress_iface),
59 G_SIGNAL_RUN_FIRST,
60 G_STRUCT_OFFSET (GimpProgressInterface, cancel),
61 NULL, NULL,
62 gimp_marshal_VOID__VOID,
63 G_TYPE_NONE, 0);
64 }
65
66
67 /* public functions */
68
69
70 GimpProgress *
gimp_progress_start(GimpProgress * progress,gboolean cancellable,const gchar * format,...)71 gimp_progress_start (GimpProgress *progress,
72 gboolean cancellable,
73 const gchar *format,
74 ...)
75 {
76 GimpProgressInterface *progress_iface;
77
78 g_return_val_if_fail (GIMP_IS_PROGRESS (progress), NULL);
79 g_return_val_if_fail (format != NULL, NULL);
80
81 progress_iface = GIMP_PROGRESS_GET_INTERFACE (progress);
82
83 if (progress_iface->start)
84 {
85 GimpProgress *ret;
86 va_list args;
87 gchar *text;
88
89 va_start (args, format);
90 text = g_strdup_vprintf (format, args);
91 va_end (args);
92
93 ret = progress_iface->start (progress, cancellable, text);
94
95 g_free (text);
96
97 return ret;
98 }
99
100 return NULL;
101 }
102
103 void
gimp_progress_end(GimpProgress * progress)104 gimp_progress_end (GimpProgress *progress)
105 {
106 GimpProgressInterface *progress_iface;
107
108 g_return_if_fail (GIMP_IS_PROGRESS (progress));
109
110 progress_iface = GIMP_PROGRESS_GET_INTERFACE (progress);
111
112 if (progress_iface->end)
113 progress_iface->end (progress);
114 }
115
116 gboolean
gimp_progress_is_active(GimpProgress * progress)117 gimp_progress_is_active (GimpProgress *progress)
118 {
119 GimpProgressInterface *progress_iface;
120
121 g_return_val_if_fail (GIMP_IS_PROGRESS (progress), FALSE);
122
123 progress_iface = GIMP_PROGRESS_GET_INTERFACE (progress);
124
125 if (progress_iface->is_active)
126 return progress_iface->is_active (progress);
127
128 return FALSE;
129 }
130
131 void
gimp_progress_set_text(GimpProgress * progress,const gchar * format,...)132 gimp_progress_set_text (GimpProgress *progress,
133 const gchar *format,
134 ...)
135 {
136 va_list args;
137 gchar *message;
138
139 g_return_if_fail (GIMP_IS_PROGRESS (progress));
140 g_return_if_fail (format != NULL);
141
142 va_start (args, format);
143 message = g_strdup_vprintf (format, args);
144 va_end (args);
145
146 gimp_progress_set_text_literal (progress, message);
147
148 g_free (message);
149 }
150
151 void
gimp_progress_set_text_literal(GimpProgress * progress,const gchar * message)152 gimp_progress_set_text_literal (GimpProgress *progress,
153 const gchar *message)
154 {
155 GimpProgressInterface *progress_iface;
156
157 g_return_if_fail (GIMP_IS_PROGRESS (progress));
158 g_return_if_fail (message != NULL);
159
160 progress_iface = GIMP_PROGRESS_GET_INTERFACE (progress);
161
162 if (progress_iface->set_text)
163 progress_iface->set_text (progress, message);
164 }
165
166 void
gimp_progress_set_value(GimpProgress * progress,gdouble percentage)167 gimp_progress_set_value (GimpProgress *progress,
168 gdouble percentage)
169 {
170 GimpProgressInterface *progress_iface;
171
172 g_return_if_fail (GIMP_IS_PROGRESS (progress));
173
174 percentage = CLAMP (percentage, 0.0, 1.0);
175
176 progress_iface = GIMP_PROGRESS_GET_INTERFACE (progress);
177
178 if (progress_iface->set_value)
179 progress_iface->set_value (progress, percentage);
180 }
181
182 gdouble
gimp_progress_get_value(GimpProgress * progress)183 gimp_progress_get_value (GimpProgress *progress)
184 {
185 GimpProgressInterface *progress_iface;
186
187 g_return_val_if_fail (GIMP_IS_PROGRESS (progress), 0.0);
188
189 progress_iface = GIMP_PROGRESS_GET_INTERFACE (progress);
190
191 if (progress_iface->get_value)
192 return progress_iface->get_value (progress);
193
194 return 0.0;
195 }
196
197 void
gimp_progress_pulse(GimpProgress * progress)198 gimp_progress_pulse (GimpProgress *progress)
199 {
200 GimpProgressInterface *progress_iface;
201
202 g_return_if_fail (GIMP_IS_PROGRESS (progress));
203
204 progress_iface = GIMP_PROGRESS_GET_INTERFACE (progress);
205
206 if (progress_iface->pulse)
207 progress_iface->pulse (progress);
208 }
209
210 guint32
gimp_progress_get_window_id(GimpProgress * progress)211 gimp_progress_get_window_id (GimpProgress *progress)
212 {
213 GimpProgressInterface *progress_iface;
214
215 g_return_val_if_fail (GIMP_IS_PROGRESS (progress), 0);
216
217 progress_iface = GIMP_PROGRESS_GET_INTERFACE (progress);
218
219 if (progress_iface->get_window_id)
220 return progress_iface->get_window_id (progress);
221
222 return 0;
223 }
224
225 gboolean
gimp_progress_message(GimpProgress * progress,Gimp * gimp,GimpMessageSeverity severity,const gchar * domain,const gchar * message)226 gimp_progress_message (GimpProgress *progress,
227 Gimp *gimp,
228 GimpMessageSeverity severity,
229 const gchar *domain,
230 const gchar *message)
231 {
232 GimpProgressInterface *progress_iface;
233
234 g_return_val_if_fail (GIMP_IS_PROGRESS (progress), FALSE);
235 g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
236 g_return_val_if_fail (domain != NULL, FALSE);
237 g_return_val_if_fail (message != NULL, FALSE);
238
239 progress_iface = GIMP_PROGRESS_GET_INTERFACE (progress);
240
241 if (progress_iface->message)
242 return progress_iface->message (progress, gimp, severity, domain, message);
243
244 return FALSE;
245 }
246
247 void
gimp_progress_cancel(GimpProgress * progress)248 gimp_progress_cancel (GimpProgress *progress)
249 {
250 g_return_if_fail (GIMP_IS_PROGRESS (progress));
251
252 g_signal_emit (progress, progress_signals[CANCEL], 0);
253 }
254
255 void
gimp_progress_update_and_flush(gint min,gint max,gint current,gpointer data)256 gimp_progress_update_and_flush (gint min,
257 gint max,
258 gint current,
259 gpointer data)
260 {
261 gimp_progress_set_value (GIMP_PROGRESS (data),
262 (gdouble) (current - min) / (gdouble) (max - min));
263
264 while (g_main_context_pending (NULL))
265 g_main_context_iteration (NULL, TRUE);
266 }
267