1 /* OGMRip - A DVD Encoder for GNOME
2 * Copyright (C) 2004-2012 Olivier Rolland <billl@users.sourceforge.net>
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 2 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, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <glib/gi18n.h>
24 #include <glade/glade.h>
25
26 #include "ogmrip-audio-codec.h"
27 #include "ogmrip-subp-codec.h"
28
29 #include "ogmrip-progress-dialog.h"
30 #include "ogmrip-helper.h"
31 #include "ogmrip-gconf.h"
32
33 #ifdef HAVE_LIBNOTIFY_SUPPORT
34 #include <libnotify/notify.h>
35 #endif /* HAVE_LIBNOTIFY_SUPPORT */
36
37 #define OGMRIP_PROGRESS_DIALOG_GET_PRIVATE(o) \
38 (G_TYPE_INSTANCE_GET_PRIVATE ((o), OGMRIP_TYPE_PROGRESS_DIALOG, OGMRipProgressDialogPriv))
39
40 #define OGMRIP_ICON_FILE "pixmaps" G_DIR_SEPARATOR_S "ogmrip.png"
41 #define OGMRIP_GLADE_FILE "ogmrip" G_DIR_SEPARATOR_S "ogmrip-progress.glade"
42 #define OGMRIP_GLADE_ROOT "root"
43
44 struct _OGMRipProgressDialogPriv
45 {
46 OGMRipEncoding *encoding;
47
48 GtkWidget *title_label;
49 GtkWidget *stage_label;
50 GtkWidget *eta_label;
51
52 GtkWidget *stage_progress;
53
54 GtkWidget *suspend_button;
55 GtkWidget *resume_button;
56 GtkWidget *cancel_button;
57 GtkWidget *quit_check;
58
59 gulong start_time;
60 gulong suspend_time;
61
62 gchar *title;
63 gchar *label;
64
65 gboolean notify;
66 gboolean can_quit;
67
68 #ifdef HAVE_LIBNOTIFY_SUPPORT
69 NotifyNotification *notification;
70 GtkStatusIcon *status_icon;
71 gboolean iconified;
72 #endif /* HAVE_LIBNOTIFY_SUPPORT */
73
74 };
75
76 static void ogmrip_progress_dialog_dispose (GObject *gobject);
77
78 #ifdef HAVE_LIBNOTIFY_SUPPORT
79 static gboolean
ogmrip_progress_dialog_get_visibility(OGMRipProgressDialog * dialog)80 ogmrip_progress_dialog_get_visibility (OGMRipProgressDialog *dialog)
81 {
82 GdkWindowState state;
83
84 #if GTK_CHECK_VERSION(2,19,0)
85 if (!gtk_widget_get_realized (GTK_WIDGET (dialog)))
86 #else
87 if (!GTK_WIDGET_REALIZED (dialog))
88 #endif
89 return FALSE;
90
91 if (dialog->priv->iconified)
92 return FALSE;
93
94 state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (dialog)));
95 if (state & (GDK_WINDOW_STATE_WITHDRAWN | GDK_WINDOW_STATE_ICONIFIED))
96 return FALSE;
97
98 return TRUE;
99 }
100
101 static gboolean
ogmrip_progress_dialog_state_changed(OGMRipProgressDialog * dialog,GdkEventWindowState * event)102 ogmrip_progress_dialog_state_changed (OGMRipProgressDialog *dialog, GdkEventWindowState *event)
103 {
104 dialog->priv->iconified = ((event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0);
105
106 return FALSE;
107 }
108
109 static void
ogmrip_progress_dialog_iconify(OGMRipProgressDialog * dialog)110 ogmrip_progress_dialog_iconify (OGMRipProgressDialog *dialog)
111 {
112 gtk_window_iconify (gtk_window_get_transient_for (GTK_WINDOW (dialog)));
113 }
114
115 static void
ogmrip_progress_dialog_cancel_menu_activated(OGMRipProgressDialog * dialog)116 ogmrip_progress_dialog_cancel_menu_activated (OGMRipProgressDialog *dialog)
117 {
118 gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
119 }
120
121 static void
ogmrip_progress_dialog_status_icon_popup_menu(OGMRipProgressDialog * dialog,guint button,guint activate_time)122 ogmrip_progress_dialog_status_icon_popup_menu (OGMRipProgressDialog *dialog, guint button, guint activate_time)
123 {
124 GtkWidget *menu, *menuitem, *image;
125
126 menu = gtk_menu_new ();
127
128 menuitem = gtk_image_menu_item_new_with_label (_("Suspend"));
129 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
130 #if GTK_CHECK_VERSION(2,18,0)
131 if (gtk_widget_get_visible (dialog->priv->suspend_button))
132 #else
133 if (GTK_WIDGET_VISIBLE (dialog->priv->suspend_button))
134 #endif
135 gtk_widget_show (menuitem);
136
137 g_signal_connect_swapped (menuitem, "activate",
138 G_CALLBACK (gtk_button_clicked), dialog->priv->suspend_button);
139
140 image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_MENU);
141 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
142 gtk_widget_show (image);
143
144 menuitem = gtk_image_menu_item_new_with_label (_("Resume"));
145 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
146 #if GTK_CHECK_VERSION(2,18,0)
147 if (gtk_widget_get_visible (dialog->priv->resume_button))
148 #else
149 if (GTK_WIDGET_VISIBLE (dialog->priv->resume_button))
150 #endif
151 gtk_widget_show (menuitem);
152
153 g_signal_connect_swapped (menuitem, "activate",
154 G_CALLBACK (gtk_button_clicked), dialog->priv->resume_button);
155
156 image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_MENU);
157 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
158 gtk_widget_show (image);
159
160 menuitem = gtk_separator_menu_item_new ();
161 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
162 gtk_widget_show (menuitem);
163
164 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_CANCEL, NULL);
165 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
166 gtk_widget_show (menuitem);
167
168 g_signal_connect_swapped (menuitem, "activate",
169 G_CALLBACK (ogmrip_progress_dialog_cancel_menu_activated), dialog);
170
171 gtk_menu_popup (GTK_MENU (menu), NULL, NULL, gtk_status_icon_position_menu,
172 dialog->priv->status_icon, button, activate_time);
173 }
174
175 #endif /* HAVE_LIBNOTIFY_SUPPORT */
176
177 static void
ogmrip_progress_dialog_set_label(OGMRipProgressDialog * dialog,const gchar * label)178 ogmrip_progress_dialog_set_label (OGMRipProgressDialog *dialog, const gchar *label)
179 {
180 gchar *str;
181
182 if (dialog->priv->label)
183 g_free (dialog->priv->label);
184 dialog->priv->label = g_strdup (label);
185
186 str = g_strdup_printf ("<i>%s</i>", label);
187 gtk_label_set_markup (GTK_LABEL (dialog->priv->stage_label), str);
188 g_free (str);
189
190 #ifdef HAVE_LIBNOTIFY_SUPPORT
191 if (dialog->priv->notification && !ogmrip_progress_dialog_get_visibility (dialog))
192 {
193 g_object_set (dialog->priv->notification, "body", label, NULL);
194 notify_notification_show (dialog->priv->notification, NULL);
195 }
196 #endif
197 }
198
199 #define SAMPLE_LENGTH 10.0
200
201 static void
ogmrip_progress_dialog_run(OGMRipProgressDialog * dialog,OGMJobSpawn * spawn,OGMRipTaskType type)202 ogmrip_progress_dialog_run (OGMRipProgressDialog *dialog, OGMJobSpawn *spawn, OGMRipTaskType type)
203 {
204 OGMDvdAudioStream *audio;
205 OGMDvdSubpStream *subp;
206 GTimeVal tv;
207
208 gchar *message;
209
210 g_get_current_time (&tv);
211 dialog->priv->start_time = tv.tv_sec;
212
213 switch (type)
214 {
215 case OGMRIP_TASK_ANALYZE:
216 ogmrip_progress_dialog_set_label (dialog, _("Analyzing video stream"));
217 break;
218 case OGMRIP_TASK_CHAPTERS:
219 ogmrip_progress_dialog_set_label (dialog, _("Extracting chapters information"));
220 break;
221 case OGMRIP_TASK_VIDEO:
222 ogmrip_progress_dialog_set_label (dialog, _("Encoding video title"));
223 break;
224 case OGMRIP_TASK_AUDIO:
225 audio = ogmrip_audio_codec_get_dvd_audio_stream (OGMRIP_AUDIO_CODEC (spawn));
226 message = g_strdup_printf (_("Extracting audio stream %d"), ogmdvd_stream_get_nr (OGMDVD_STREAM (audio)) + 1);
227 ogmrip_progress_dialog_set_label (dialog, message);
228 g_free (message);
229 break;
230 case OGMRIP_TASK_SUBP:
231 subp = ogmrip_subp_codec_get_dvd_subp_stream (OGMRIP_SUBP_CODEC (spawn));
232 message = g_strdup_printf (_("Extracting subtitle stream %d"), ogmdvd_stream_get_nr (OGMDVD_STREAM (subp)) + 1);
233 ogmrip_progress_dialog_set_label (dialog, message);
234 g_free (message);
235 break;
236 case OGMRIP_TASK_MERGE:
237 ogmrip_progress_dialog_set_label (dialog, _("Merging audio and video streams"));
238 break;
239 case OGMRIP_TASK_BACKUP:
240 ogmrip_progress_dialog_set_label (dialog, _("DVD backup"));
241 break;
242 case OGMRIP_TASK_TEST:
243 ogmrip_progress_dialog_set_label (dialog, _("Compressibility Test"));
244 break;
245 case OGMRIP_TASK_CROP:
246 ogmrip_progress_dialog_set_label (dialog, _("Cropping"));
247 break;
248 }
249
250 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (dialog->priv->stage_progress), 0);
251 }
252
253 static void
ogmrip_progress_dialog_progress(OGMRipProgressDialog * dialog,gdouble fraction)254 ogmrip_progress_dialog_progress (OGMRipProgressDialog *dialog, gdouble fraction)
255 {
256 GtkWindow *parent;
257 GTimeVal tv;
258 gchar *str;
259 gulong eta;
260
261 if (!dialog->priv->start_time)
262 {
263 g_get_current_time (&tv);
264 dialog->priv->start_time = tv.tv_sec;
265 }
266
267 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (dialog->priv->stage_progress), CLAMP (fraction, 0.0, 1.0));
268
269 g_get_current_time (&tv);
270 eta = (1.0 - fraction) * (tv.tv_sec - dialog->priv->start_time) / fraction;
271
272 if (eta >= 3600)
273 str = g_strdup_printf ("%ld hour(s) %ld minute(s)", eta / 3600, (eta % 3600) / 60);
274 else
275 str = g_strdup_printf ("%ld minute(s)", eta / 60);
276
277 gtk_label_set_text (GTK_LABEL (dialog->priv->eta_label), str);
278 g_free (str);
279
280 #ifdef HAVE_LIBNOTIFY_SUPPORT
281 if (dialog->priv->status_icon)
282 {
283 str = g_strdup_printf (_("%s: %02.0lf%% done"), dialog->priv->label, fraction * 100);
284 #if GTK_CHECK_VERSION(2,15,0)
285 gtk_status_icon_set_tooltip_text (dialog->priv->status_icon, str);
286 #else
287 gtk_status_icon_set_tooltip (dialog->priv->status_icon, str);
288 #endif /* GTK_CHECK_VERSION */
289 g_free (str);
290 }
291 #endif /* HAVE_LIBNOTIFY_SUPPORT */
292
293 parent = gtk_window_get_transient_for (GTK_WINDOW (dialog));
294 if (parent)
295 {
296 gchar *title;
297
298 title = g_strdup_printf ("OGMRip: %s: %.0f%%", dialog->priv->label, CLAMP (fraction, 0.0, 1.0) * 100);
299 gtk_window_set_title (parent, title);
300 g_free (title);
301 }
302 }
303
304 static void
ogmrip_progress_dialog_suspend(OGMRipProgressDialog * dialog)305 ogmrip_progress_dialog_suspend (OGMRipProgressDialog *dialog)
306 {
307 GTimeVal tv;
308
309 g_get_current_time (&tv);
310 dialog->priv->suspend_time = tv.tv_sec;
311 }
312
313 static void
ogmrip_progress_dialog_resume(OGMRipProgressDialog * dialog)314 ogmrip_progress_dialog_resume (OGMRipProgressDialog *dialog)
315 {
316 GTimeVal tv;
317
318 g_get_current_time (&tv);
319 dialog->priv->start_time += tv.tv_sec - dialog->priv->suspend_time;
320 }
321
322 static void
ogmrip_progress_dialog_task_event(OGMRipProgressDialog * dialog,OGMRipEncodingTask * task,OGMRipEncoding * encoding)323 ogmrip_progress_dialog_task_event (OGMRipProgressDialog *dialog, OGMRipEncodingTask *task, OGMRipEncoding *encoding)
324 {
325 switch (task->event)
326 {
327 case OGMRIP_TASK_RUN:
328 ogmrip_progress_dialog_run (dialog, task->spawn, task->type);
329 break;
330 case OGMRIP_TASK_PROGRESS:
331 ogmrip_progress_dialog_progress (dialog, task->detail.fraction);
332 break;
333 case OGMRIP_TASK_SUSPEND:
334 ogmrip_progress_dialog_suspend (dialog);
335 break;
336 case OGMRIP_TASK_RESUME:
337 ogmrip_progress_dialog_resume (dialog);
338 break;
339 default:
340 break;
341 }
342 }
343
G_DEFINE_TYPE(OGMRipProgressDialog,ogmrip_progress_dialog,GTK_TYPE_DIALOG)344 G_DEFINE_TYPE (OGMRipProgressDialog, ogmrip_progress_dialog, GTK_TYPE_DIALOG)
345
346 static void
347 ogmrip_progress_dialog_class_init (OGMRipProgressDialogClass *klass)
348 {
349 GObjectClass *gobject_class;
350
351 gobject_class = G_OBJECT_CLASS (klass);
352 gobject_class->dispose = ogmrip_progress_dialog_dispose;
353
354 g_type_class_add_private (klass, sizeof (OGMRipProgressDialogPriv));
355 }
356
357 static void
ogmrip_progress_dialog_init(OGMRipProgressDialog * dialog)358 ogmrip_progress_dialog_init (OGMRipProgressDialog *dialog)
359 {
360 GtkWidget *area, *root, *image;
361 GtkSizeGroup *group;
362 GladeXML *xml;
363
364 #ifdef HAVE_LIBNOTIFY_SUPPORT
365 GtkAccelGroup *accel_group;
366 GClosure *closure;
367 #endif /* HAVE_LIBNOTIFY_SUPPORT */
368
369 dialog->priv = OGMRIP_PROGRESS_DIALOG_GET_PRIVATE (dialog);
370
371 dialog->priv->can_quit = TRUE;
372
373 xml = glade_xml_new (OGMRIP_DATA_DIR G_DIR_SEPARATOR_S OGMRIP_GLADE_FILE, OGMRIP_GLADE_ROOT, NULL);
374 if (!xml)
375 {
376 g_warning ("Could not find " OGMRIP_GLADE_FILE);
377 return;
378 }
379
380 group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
381
382 area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
383
384 gtk_button_box_set_layout (GTK_BUTTON_BOX (area), GTK_BUTTONBOX_EDGE);
385
386 dialog->priv->resume_button = gtk_button_new_with_mnemonic (_("Resume"));
387 gtk_dialog_add_action_widget (GTK_DIALOG (dialog), dialog->priv->resume_button, OGMRIP_RESPONSE_RESUME);
388 gtk_size_group_add_widget (group, dialog->priv->resume_button);
389
390 image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_BUTTON);
391 gtk_button_set_image (GTK_BUTTON (dialog->priv->resume_button), image);
392
393 dialog->priv->suspend_button = gtk_button_new_with_mnemonic (_("Suspend"));
394 gtk_dialog_add_action_widget (GTK_DIALOG (dialog), dialog->priv->suspend_button, OGMRIP_RESPONSE_SUSPEND);
395 gtk_size_group_add_widget (group, dialog->priv->suspend_button);
396 gtk_widget_show (dialog->priv->suspend_button);
397
398 image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_BUTTON);
399 gtk_button_set_image (GTK_BUTTON (dialog->priv->suspend_button), image);
400
401 dialog->priv->cancel_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
402
403 gtk_window_set_title (GTK_WINDOW (dialog), _("Progress"));
404 gtk_window_set_default_size (GTK_WINDOW (dialog), 450, -1);
405 gtk_window_set_icon_from_stock (GTK_WINDOW (dialog), GTK_STOCK_EXECUTE);
406 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
407 #if !GTK_CHECK_VERSION(2,22,0)
408 gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
409 #endif
410
411 area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
412
413 root = glade_xml_get_widget (xml, OGMRIP_GLADE_ROOT);
414 gtk_container_add (GTK_CONTAINER (area), root);
415 gtk_widget_show (root);
416
417 #ifdef HAVE_LIBNOTIFY_SUPPORT
418 dialog->priv->status_icon = gtk_status_icon_new_from_file (OGMRIP_DATA_DIR G_DIR_SEPARATOR_S OGMRIP_ICON_FILE);
419
420 g_signal_connect_swapped (dialog->priv->status_icon, "popup_menu",
421 G_CALLBACK (ogmrip_progress_dialog_status_icon_popup_menu), dialog);
422
423 dialog->priv->notification = notify_notification_new ("Dummy", "Dummy", NULL);
424 g_signal_connect (dialog, "window-state-event",
425 G_CALLBACK (ogmrip_progress_dialog_state_changed), NULL);
426
427 accel_group = gtk_accel_group_new ();
428 gtk_window_add_accel_group (GTK_WINDOW (dialog), accel_group);
429
430 closure = g_cclosure_new_swap (G_CALLBACK (ogmrip_progress_dialog_iconify), dialog, NULL);
431 gtk_accel_group_connect (accel_group, 'w', GDK_CONTROL_MASK, 0, closure);
432 g_closure_unref (closure);
433 #endif /* HAVE_LIBNOTIFY_SUPPORT */
434
435 dialog->priv->title_label = glade_xml_get_widget (xml, "title-label");
436 dialog->priv->stage_label = glade_xml_get_widget (xml, "stage-label");
437 dialog->priv->stage_progress = glade_xml_get_widget (xml, "stage-progress");
438 dialog->priv->eta_label = glade_xml_get_widget (xml, "eta-label");
439 dialog->priv->quit_check = glade_xml_get_widget (xml, "quit-check");
440
441 g_object_unref (xml);
442 }
443
444 static void
ogmrip_progress_dialog_dispose(GObject * gobject)445 ogmrip_progress_dialog_dispose (GObject *gobject)
446 {
447 OGMRipProgressDialog *dialog = OGMRIP_PROGRESS_DIALOG (gobject);
448
449 if (dialog->priv->encoding)
450 {
451 g_signal_handlers_disconnect_by_func (dialog->priv->encoding,
452 ogmrip_progress_dialog_task_event, dialog);
453 g_object_unref (dialog->priv->encoding);
454 dialog->priv->encoding = NULL;
455 }
456
457 if (dialog->priv->title)
458 g_free (dialog->priv->title);
459 dialog->priv->title = NULL;
460
461 if (dialog->priv->label)
462 g_free (dialog->priv->label);
463 dialog->priv->label = NULL;
464
465 #ifdef HAVE_LIBNOTIFY_SUPPORT
466 if (dialog->priv->notification)
467 g_object_unref (dialog->priv->notification);
468 dialog->priv->notification = NULL;
469
470 if (dialog->priv->status_icon)
471 g_object_unref (dialog->priv->status_icon);
472 dialog->priv->status_icon = NULL;
473 #endif /* HAVE_LIBNOTIFY_SUPPORT */
474
475 G_OBJECT_CLASS (ogmrip_progress_dialog_parent_class)->dispose (gobject);
476 }
477
478 GtkWidget *
ogmrip_progress_dialog_new(void)479 ogmrip_progress_dialog_new (void)
480 {
481 return g_object_new (OGMRIP_TYPE_PROGRESS_DIALOG, NULL);
482 }
483
484 static void
ogmrip_progress_dialog_set_title(OGMRipProgressDialog * dialog,const gchar * title)485 ogmrip_progress_dialog_set_title (OGMRipProgressDialog *dialog, const gchar *title)
486 {
487 gchar *str;
488
489 g_return_if_fail (OGMRIP_IS_PROGRESS_DIALOG (dialog));
490 g_return_if_fail (title != NULL);
491
492 if (dialog->priv->title)
493 g_free (dialog->priv->title);
494 dialog->priv->title = g_markup_escape_text (title, -1);
495
496 str = g_strdup_printf ("<big><b>%s</b></big>", title);
497 gtk_label_set_markup (GTK_LABEL (dialog->priv->title_label), str);
498 g_free (str);
499
500 #ifdef HAVE_LIBNOTIFY_SUPPORT
501 notify_notification_update (dialog->priv->notification, title, "Dummy",
502 OGMRIP_DATA_DIR G_DIR_SEPARATOR_S OGMRIP_ICON_FILE);
503 #endif /* HAVE_LIBNOTIFY_SUPPORT */
504 }
505
506 void
ogmrip_progress_dialog_set_encoding(OGMRipProgressDialog * dialog,OGMRipEncoding * encoding)507 ogmrip_progress_dialog_set_encoding (OGMRipProgressDialog *dialog, OGMRipEncoding *encoding)
508 {
509 g_return_if_fail (OGMRIP_IS_PROGRESS_DIALOG (dialog));
510 g_return_if_fail (encoding == NULL || OGMRIP_IS_ENCODING (encoding));
511
512 if (encoding != dialog->priv->encoding)
513 {
514 g_object_ref (encoding);
515
516 if (dialog->priv->encoding)
517 {
518 g_signal_handlers_disconnect_by_func (dialog->priv->encoding,
519 ogmrip_progress_dialog_task_event, dialog);
520
521 g_object_unref (dialog->priv->encoding);
522 }
523
524 dialog->priv->encoding = encoding;
525
526 g_signal_connect_swapped (encoding, "task",
527 G_CALLBACK (ogmrip_progress_dialog_task_event), dialog);
528
529 ogmrip_progress_dialog_set_title (dialog, ogmrip_encoding_get_label (encoding));
530
531 }
532 }
533
534 OGMRipEncoding *
ogmrip_progress_dialog_get_encoding(OGMRipProgressDialog * dialog)535 ogmrip_progress_dialog_get_encoding (OGMRipProgressDialog *dialog)
536 {
537 return dialog->priv->encoding;
538 }
539
540 void
ogmrip_progress_dialog_can_quit(OGMRipProgressDialog * dialog,gboolean can_quit)541 ogmrip_progress_dialog_can_quit (OGMRipProgressDialog *dialog, gboolean can_quit)
542 {
543 if (can_quit != dialog->priv->can_quit)
544 {
545 dialog->priv->can_quit = can_quit;
546 g_object_set (G_OBJECT (dialog->priv->quit_check),
547 "visible", can_quit, "sensitive", can_quit, NULL);
548 }
549 }
550
551 gboolean
ogmrip_progress_dialog_get_quit(OGMRipProgressDialog * dialog)552 ogmrip_progress_dialog_get_quit (OGMRipProgressDialog *dialog)
553 {
554 return dialog->priv->can_quit &&
555 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->quit_check));
556 }
557
558