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