1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3 * Libbrasero-burn
4 * Copyright (C) Philippe Rouquier 2005-2009 <bonfire-app@wanadoo.fr>
5 *
6 * Libbrasero-burn is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The Libbrasero-burn authors hereby grant permission for non-GPL compatible
12 * GStreamer plugins to be used and distributed together with GStreamer
13 * and Libbrasero-burn. This permission is above and beyond the permissions granted
14 * by the GPL license by which Libbrasero-burn is covered. If you modify this code
15 * you may extend this exception to your version of the code, but you are not
16 * obligated to do so. If you do not wish to do so, delete this exception
17 * statement from your version.
18 *
19 * Libbrasero-burn is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to:
26 * The Free Software Foundation, Inc.,
27 * 51 Franklin Street, Fifth Floor
28 * Boston, MA 02110-1301, USA.
29 */
30
31 #ifdef HAVE_CONFIG_H
32 # include <config.h>
33 #endif
34
35 #include <glib.h>
36 #include <glib-object.h>
37 #include <glib/gi18n-lib.h>
38
39 #include <gdk/gdkx.h>
40 #include <gtk/gtk.h>
41
42 #include "burn-basics.h"
43
44 #include "brasero-medium.h"
45 #include "brasero-medium-selection-priv.h"
46
47 #include "burn-debug.h"
48 #include "brasero-session.h"
49 #include "brasero-session-helper.h"
50 #include "brasero-burn-options.h"
51 #include "brasero-video-options.h"
52 #include "brasero-src-image.h"
53 #include "brasero-src-selection.h"
54 #include "brasero-session-cfg.h"
55 #include "brasero-dest-selection.h"
56 #include "brasero-medium-properties.h"
57 #include "brasero-status-dialog.h"
58 #include "brasero-track-stream.h"
59 #include "brasero-track-data-cfg.h"
60 #include "brasero-track-image-cfg.h"
61
62 #include "brasero-notify.h"
63 #include "brasero-misc.h"
64 #include "brasero-pk.h"
65
66 typedef struct _BraseroBurnOptionsPrivate BraseroBurnOptionsPrivate;
67 struct _BraseroBurnOptionsPrivate
68 {
69 BraseroSessionCfg *session;
70
71 GtkSizeGroup *size_group;
72
73 GtkWidget *source;
74 GtkWidget *source_placeholder;
75 GtkWidget *message_input;
76 GtkWidget *selection;
77 GtkWidget *properties;
78 GtkWidget *message_output;
79 GtkWidget *options;
80 GtkWidget *options_placeholder;
81 GtkWidget *button;
82
83 GtkWidget *burn;
84 GtkWidget *burn_multi;
85
86 guint not_ready_id;
87 GtkWidget *status_dialog;
88
89 GCancellable *cancel;
90
91 guint is_valid:1;
92
93 guint has_image:1;
94 guint has_audio:1;
95 guint has_video:1;
96 guint has_data:1;
97 guint has_disc:1;
98 };
99
100 #define BRASERO_BURN_OPTIONS_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_BURN_OPTIONS, BraseroBurnOptionsPrivate))
101
102 enum {
103 PROP_0,
104 PROP_SESSION
105 };
106
107 G_DEFINE_TYPE (BraseroBurnOptions, brasero_burn_options, GTK_TYPE_DIALOG);
108
109 static void
brasero_burn_options_add_source(BraseroBurnOptions * self,const gchar * title,...)110 brasero_burn_options_add_source (BraseroBurnOptions *self,
111 const gchar *title,
112 ...)
113 {
114 va_list vlist;
115 GtkWidget *child;
116 GSList *list = NULL;
117 BraseroBurnOptionsPrivate *priv;
118
119 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
120
121 /* create message queue for input */
122 priv->message_input = brasero_notify_new ();
123 list = g_slist_prepend (list, priv->message_input);
124
125 va_start (vlist, title);
126 while ((child = va_arg (vlist, GtkWidget *))) {
127 GtkWidget *hbox;
128 GtkWidget *alignment;
129
130 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
131 gtk_widget_show (hbox);
132
133 gtk_box_pack_start (GTK_BOX (hbox), child, TRUE, TRUE, 0);
134
135 alignment = gtk_alignment_new (0.0, 0.5, 0., 0.);
136 gtk_widget_show (alignment);
137 gtk_size_group_add_widget (priv->size_group, alignment);
138 gtk_box_pack_start (GTK_BOX (hbox), alignment, FALSE, FALSE, 0);
139
140 list = g_slist_prepend (list, hbox);
141 }
142 va_end (vlist);
143
144 priv->source = brasero_utils_pack_properties_list (title, list);
145 g_slist_free (list);
146
147 gtk_container_add (GTK_CONTAINER (priv->source_placeholder), priv->source);
148 gtk_widget_show (priv->source_placeholder);
149 }
150
151 /**
152 * brasero_burn_options_add_options:
153 * @dialog: a #BraseroBurnOptions
154 * @options: a #GtkWidget
155 *
156 * Adds some new options to be displayed in the dialog.
157 **/
158
159 void
brasero_burn_options_add_options(BraseroBurnOptions * self,GtkWidget * options)160 brasero_burn_options_add_options (BraseroBurnOptions *self,
161 GtkWidget *options)
162 {
163 BraseroBurnOptionsPrivate *priv;
164
165 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
166 gtk_box_pack_start (GTK_BOX (priv->options), options, FALSE, TRUE, 0);
167 gtk_widget_show (priv->options);
168 }
169
170 static void
brasero_burn_options_set_type_shown(BraseroBurnOptions * self,BraseroMediaType type)171 brasero_burn_options_set_type_shown (BraseroBurnOptions *self,
172 BraseroMediaType type)
173 {
174 BraseroBurnOptionsPrivate *priv;
175
176 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
177 brasero_medium_selection_show_media_type (BRASERO_MEDIUM_SELECTION (priv->selection), type);
178 }
179
180 static void
brasero_burn_options_message_response_cb(BraseroDiscMessage * message,GtkResponseType response,BraseroBurnOptions * self)181 brasero_burn_options_message_response_cb (BraseroDiscMessage *message,
182 GtkResponseType response,
183 BraseroBurnOptions *self)
184 {
185 if (response == GTK_RESPONSE_OK) {
186 BraseroBurnOptionsPrivate *priv;
187
188 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
189 brasero_session_cfg_add_flags (priv->session, BRASERO_BURN_FLAG_OVERBURN);
190 }
191 }
192
193 static void
brasero_burn_options_message_response_span_cb(BraseroDiscMessage * message,GtkResponseType response,BraseroBurnOptions * self)194 brasero_burn_options_message_response_span_cb (BraseroDiscMessage *message,
195 GtkResponseType response,
196 BraseroBurnOptions *self)
197 {
198 if (response == GTK_RESPONSE_OK) {
199 BraseroBurnOptionsPrivate *priv;
200
201 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
202 brasero_session_span_start (BRASERO_SESSION_SPAN (priv->session));
203 if (brasero_session_span_next (BRASERO_SESSION_SPAN (priv->session)) == BRASERO_BURN_ERR)
204 BRASERO_BURN_LOG ("Spanning failed\n");
205 }
206 }
207
208 #define BRASERO_BURN_OPTIONS_NO_MEDIUM_WARNING 1000
209
210 static void
brasero_burn_options_update_no_medium_warning(BraseroBurnOptions * self)211 brasero_burn_options_update_no_medium_warning (BraseroBurnOptions *self)
212 {
213 BraseroBurnOptionsPrivate *priv;
214
215 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
216
217 if (!priv->is_valid
218 || !brasero_burn_session_is_dest_file (BRASERO_BURN_SESSION (priv->session))
219 || brasero_medium_selection_get_media_num (BRASERO_MEDIUM_SELECTION (priv->selection)) != 1) {
220 brasero_notify_message_remove (priv->message_output,
221 BRASERO_BURN_OPTIONS_NO_MEDIUM_WARNING);
222 return;
223 }
224
225 /* The user may have forgotten to insert a disc so remind him of that if
226 * there aren't any other possibility in the selection */
227 brasero_notify_message_add (priv->message_output,
228 _("Please insert a writable CD or DVD if you don't want to write to an image file."),
229 NULL,
230 -1,
231 BRASERO_BURN_OPTIONS_NO_MEDIUM_WARNING);
232 }
233
234 static void
brasero_burn_options_not_ready_dialog_cancel_cb(GtkDialog * dialog,guint response,gpointer data)235 brasero_burn_options_not_ready_dialog_cancel_cb (GtkDialog *dialog,
236 guint response,
237 gpointer data)
238 {
239 BraseroBurnOptionsPrivate *priv;
240
241 priv = BRASERO_BURN_OPTIONS_PRIVATE (data);
242
243 if (priv->not_ready_id) {
244 g_source_remove (priv->not_ready_id);
245 priv->not_ready_id = 0;
246 }
247 gtk_widget_set_sensitive (GTK_WIDGET (data), TRUE);
248
249 if (response != GTK_RESPONSE_OK)
250 gtk_dialog_response (GTK_DIALOG (data),
251 GTK_RESPONSE_CANCEL);
252 else {
253 priv->status_dialog = NULL;
254 gtk_widget_destroy (GTK_WIDGET (dialog));
255 }
256 }
257
258 static gboolean
brasero_burn_options_not_ready_dialog_show_cb(gpointer data)259 brasero_burn_options_not_ready_dialog_show_cb (gpointer data)
260 {
261 BraseroBurnOptionsPrivate *priv;
262
263 priv = BRASERO_BURN_OPTIONS_PRIVATE (data);
264
265 /* icon should be set by now */
266 gtk_window_set_icon_name (GTK_WINDOW (priv->status_dialog),
267 gtk_window_get_icon_name (GTK_WINDOW (data)));
268
269 gtk_widget_show (priv->status_dialog);
270 priv->not_ready_id = 0;
271 return FALSE;
272 }
273
274 static void
brasero_burn_options_not_ready_dialog_shown_cb(GtkWidget * widget,gpointer data)275 brasero_burn_options_not_ready_dialog_shown_cb (GtkWidget *widget,
276 gpointer data)
277 {
278 BraseroBurnOptionsPrivate *priv;
279
280 priv = BRASERO_BURN_OPTIONS_PRIVATE (data);
281 if (priv->not_ready_id) {
282 g_source_remove (priv->not_ready_id);
283 priv->not_ready_id = 0;
284 }
285 }
286
287 static void
brasero_burn_options_setup_buttons(BraseroBurnOptions * self)288 brasero_burn_options_setup_buttons (BraseroBurnOptions *self)
289 {
290 BraseroBurnOptionsPrivate *priv;
291 BraseroTrackType *type;
292 gchar *label_m = "";
293 gchar *label;
294 gchar *icon;
295
296 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
297
298 /* add the new widgets */
299 type = brasero_track_type_new ();
300 brasero_burn_session_get_input_type (BRASERO_BURN_SESSION (priv->session), type);
301 if (brasero_burn_session_is_dest_file (BRASERO_BURN_SESSION (priv->session))) {
302 label = _("Create _Image");
303 icon = "iso-image-new";
304 }
305 else if (brasero_track_type_get_has_medium (type)) {
306 /* Translators: This is a verb, an action */
307 label = _("_Copy");
308 icon = "media-optical-copy";
309
310 label_m = _("Make _Several Copies");
311 }
312 else {
313 /* Translators: This is a verb, an action */
314 label = _("_Burn");
315 icon = "media-optical-burn";
316
317 label_m = _("Burn _Several Copies");
318 }
319
320 if (priv->burn_multi)
321 gtk_button_set_label (GTK_BUTTON (priv->burn_multi), label_m);
322 else
323 priv->burn_multi = gtk_dialog_add_button (GTK_DIALOG (self),
324 label_m,
325 GTK_RESPONSE_ACCEPT);
326
327 if (brasero_burn_session_is_dest_file (BRASERO_BURN_SESSION (priv->session)))
328 gtk_widget_hide (priv->burn_multi);
329 else
330 gtk_widget_show (priv->burn_multi);
331
332 if (priv->burn)
333 gtk_button_set_label (GTK_BUTTON (priv->burn), label);
334 else
335 priv->burn = gtk_dialog_add_button (GTK_DIALOG (self),
336 label,
337 GTK_RESPONSE_OK);
338
339 gtk_button_set_image (GTK_BUTTON (priv->burn), gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_BUTTON));
340
341 gtk_widget_set_sensitive (priv->burn, priv->is_valid);
342 gtk_widget_set_sensitive (priv->burn_multi, priv->is_valid);
343
344 brasero_track_type_free (type);
345 }
346
347 static void
brasero_burn_options_update_valid(BraseroBurnOptions * self)348 brasero_burn_options_update_valid (BraseroBurnOptions *self)
349 {
350 BraseroBurnOptionsPrivate *priv;
351 BraseroSessionError valid;
352 BraseroDrive *drive;
353
354 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
355
356 valid = brasero_session_cfg_get_error (priv->session);
357 priv->is_valid = BRASERO_SESSION_IS_VALID (valid);
358
359 brasero_burn_options_setup_buttons (self);
360
361 gtk_widget_set_sensitive (priv->options, priv->is_valid);
362 /* Ensure the user can always change the properties (i.e. file location)
363 * the target is a fake drive */
364 drive = brasero_burn_session_get_burner (BRASERO_BURN_SESSION (priv->session));
365 if (drive && brasero_drive_is_fake (drive))
366 gtk_widget_set_sensitive (priv->properties, TRUE);
367 else
368 gtk_widget_set_sensitive (priv->properties, priv->is_valid);
369
370 if (priv->message_input) {
371 gtk_widget_hide (priv->message_input);
372 brasero_notify_message_remove (priv->message_input,
373 BRASERO_NOTIFY_CONTEXT_SIZE);
374 }
375
376 brasero_notify_message_remove (priv->message_output,
377 BRASERO_NOTIFY_CONTEXT_SIZE);
378
379 if (valid == BRASERO_SESSION_NOT_READY) {
380 if (!priv->not_ready_id && !priv->status_dialog) {
381 gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
382 priv->status_dialog = brasero_status_dialog_new (BRASERO_BURN_SESSION (priv->session), GTK_WIDGET (self));
383 g_signal_connect (priv->status_dialog,
384 "response",
385 G_CALLBACK (brasero_burn_options_not_ready_dialog_cancel_cb),
386 self);
387
388 g_signal_connect (priv->status_dialog,
389 "show",
390 G_CALLBACK (brasero_burn_options_not_ready_dialog_shown_cb),
391 self);
392 g_signal_connect (priv->status_dialog,
393 "user-interaction",
394 G_CALLBACK (brasero_burn_options_not_ready_dialog_shown_cb),
395 self);
396
397 priv->not_ready_id = g_timeout_add_seconds (1,
398 brasero_burn_options_not_ready_dialog_show_cb,
399 self);
400 }
401 }
402 else {
403 gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE);
404 if (priv->status_dialog) {
405 gtk_widget_destroy (priv->status_dialog);
406 priv->status_dialog = NULL;
407 }
408
409 if (priv->not_ready_id) {
410 g_source_remove (priv->not_ready_id);
411 priv->not_ready_id = 0;
412 }
413 }
414
415 if (valid == BRASERO_SESSION_INSUFFICIENT_SPACE) {
416 goffset min_disc_size;
417 goffset available_space;
418
419 min_disc_size = brasero_session_span_get_max_space (BRASERO_SESSION_SPAN (priv->session));
420
421 /* One rule should be that the maximum batch size should not exceed the disc size
422 * FIXME: we could change it into a dialog telling the user what is the maximum
423 * size required. */
424 available_space = brasero_burn_session_get_available_medium_space (BRASERO_BURN_SESSION (priv->session));
425
426 /* Here there is an alternative: we may be able to span the data
427 * across multiple media. So try that. */
428 if (available_space > min_disc_size
429 && brasero_session_span_possible (BRASERO_SESSION_SPAN (priv->session)) == BRASERO_BURN_RETRY) {
430 GtkWidget *message;
431
432 message = brasero_notify_message_add (priv->message_output,
433 _("Would you like to burn the selection of files across several media?"),
434 _("The data size is too large for the disc even with the overburn option."),
435 -1,
436 BRASERO_NOTIFY_CONTEXT_SIZE);
437
438 gtk_widget_set_tooltip_text (gtk_info_bar_add_button (GTK_INFO_BAR (message),
439 _("_Burn Several Discs"),
440 GTK_RESPONSE_OK),
441 _("Burn the selection of files across several media"));
442
443 g_signal_connect (message,
444 "response",
445 G_CALLBACK (brasero_burn_options_message_response_span_cb),
446 self);
447 }
448 else
449 brasero_notify_message_add (priv->message_output,
450 _("Please choose another CD or DVD or insert a new one."),
451 _("The data size is too large for the disc even with the overburn option."),
452 -1,
453 BRASERO_NOTIFY_CONTEXT_SIZE);
454 }
455 else if (valid == BRASERO_SESSION_NO_OUTPUT) {
456 brasero_notify_message_add (priv->message_output,
457 _("Please insert a writable CD or DVD."),
458 NULL,
459 -1,
460 BRASERO_NOTIFY_CONTEXT_SIZE);
461 }
462 else if (valid == BRASERO_SESSION_NO_CD_TEXT) {
463 brasero_notify_message_add (priv->message_output,
464 _("No track information (artist, title, ...) will be written to the disc."),
465 _("This is not supported by the current active burning backend."),
466 -1,
467 BRASERO_NOTIFY_CONTEXT_SIZE);
468 }
469 else if (valid == BRASERO_SESSION_EMPTY) {
470 BraseroTrackType *type;
471
472 type = brasero_track_type_new ();
473 brasero_burn_session_get_input_type (BRASERO_BURN_SESSION (priv->session), type);
474
475 if (brasero_track_type_get_has_data (type))
476 brasero_notify_message_add (priv->message_output,
477 _("Please add files."),
478 _("There are no files to write to disc"),
479 -1,
480 BRASERO_NOTIFY_CONTEXT_SIZE);
481 else if (!BRASERO_STREAM_FORMAT_HAS_VIDEO (brasero_track_type_get_stream_format (type)))
482 brasero_notify_message_add (priv->message_output,
483 _("Please add songs."),
484 _("There are no songs to write to disc"),
485 -1,
486 BRASERO_NOTIFY_CONTEXT_SIZE);
487 else
488 brasero_notify_message_add (priv->message_output,
489 _("Please add videos."),
490 _("There are no videos to write to disc"),
491 -1,
492 BRASERO_NOTIFY_CONTEXT_SIZE);
493 brasero_track_type_free (type);
494 gtk_window_resize (GTK_WINDOW (self), 10, 10);
495 return;
496 }
497 else if (valid == BRASERO_SESSION_NO_INPUT_MEDIUM) {
498 if (priv->message_input) {
499 gtk_widget_show (priv->message_input);
500 brasero_notify_message_add (priv->message_input,
501 _("Please insert a disc holding data."),
502 _("There is no inserted disc to copy."),
503 -1,
504 BRASERO_NOTIFY_CONTEXT_SIZE);
505 }
506 }
507 else if (valid == BRASERO_SESSION_NO_INPUT_IMAGE) {
508 if (priv->message_input) {
509 gtk_widget_show (priv->message_input);
510 brasero_notify_message_add (priv->message_input,
511 _("Please select a disc image."),
512 _("There is no selected disc image."),
513 -1,
514 BRASERO_NOTIFY_CONTEXT_SIZE);
515 }
516 }
517 else if (valid == BRASERO_SESSION_UNKNOWN_IMAGE) {
518 if (priv->message_input) {
519 gtk_widget_show (priv->message_input);
520 brasero_notify_message_add (priv->message_input,
521 /* Translators: this is a disc image not a picture */
522 C_("disc", "Please select another image."),
523 _("It doesn't appear to be a valid disc image or a valid cue file."),
524 -1,
525 BRASERO_NOTIFY_CONTEXT_SIZE);
526 }
527 }
528 else if (valid == BRASERO_SESSION_DISC_PROTECTED) {
529 if (priv->message_input) {
530 gtk_widget_show (priv->message_input);
531 brasero_notify_message_add (priv->message_input,
532 _("Please insert a disc that is not copy protected."),
533 _("All required applications and libraries are not installed."),
534 -1,
535 BRASERO_NOTIFY_CONTEXT_SIZE);
536 }
537 }
538 else if (valid == BRASERO_SESSION_NOT_SUPPORTED) {
539 brasero_notify_message_add (priv->message_output,
540 _("Please replace the disc with a supported CD or DVD."),
541 NULL,
542 -1,
543 BRASERO_NOTIFY_CONTEXT_SIZE);
544 }
545 else if (valid == BRASERO_SESSION_OVERBURN_NECESSARY) {
546 GtkWidget *message;
547
548 message = brasero_notify_message_add (priv->message_output,
549 _("Would you like to burn beyond the disc's reported capacity?"),
550 _("The data size is too large for the disc and you must remove files from the selection otherwise."
551 "\nYou may want to use this option if you're using 90 or 100 min CD-R(W) which cannot be properly recognised and therefore need overburn option."
552 "\nNOTE: This option might cause failure."),
553 -1,
554 BRASERO_NOTIFY_CONTEXT_SIZE);
555
556 gtk_widget_set_tooltip_text (gtk_info_bar_add_button (GTK_INFO_BAR (message),
557 _("_Overburn"),
558 GTK_RESPONSE_OK),
559 _("Burn beyond the disc's reported capacity"));
560
561 g_signal_connect (message,
562 "response",
563 G_CALLBACK (brasero_burn_options_message_response_cb),
564 self);
565 }
566 else if (brasero_burn_session_same_src_dest_drive (BRASERO_BURN_SESSION (priv->session))) {
567 /* The medium is valid but it's a special case */
568 brasero_notify_message_add (priv->message_output,
569 _("The drive that holds the source disc will also be the one used to record."),
570 _("A new writable disc will be required once the currently loaded one has been copied."),
571 -1,
572 BRASERO_NOTIFY_CONTEXT_SIZE);
573 gtk_widget_show_all (priv->message_output);
574 }
575
576 brasero_burn_options_update_no_medium_warning (self);
577 gtk_window_resize (GTK_WINDOW (self), 10, 10);
578 }
579
580 static void
brasero_burn_options_valid_cb(BraseroSessionCfg * session,BraseroBurnOptions * self)581 brasero_burn_options_valid_cb (BraseroSessionCfg *session,
582 BraseroBurnOptions *self)
583 {
584 brasero_burn_options_update_valid (self);
585 }
586
587 static void
brasero_burn_options_init(BraseroBurnOptions * object)588 brasero_burn_options_init (BraseroBurnOptions *object)
589 {
590 }
591
592 /**
593 * To build anything we need to have the session set first
594 */
595
596 static void
brasero_burn_options_build_contents(BraseroBurnOptions * object)597 brasero_burn_options_build_contents (BraseroBurnOptions *object)
598 {
599 BraseroBurnOptionsPrivate *priv;
600 GtkWidget *content_area;
601 GtkWidget *selection;
602 GtkWidget *alignment;
603 gchar *string;
604
605 priv = BRASERO_BURN_OPTIONS_PRIVATE (object);
606
607 priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
608
609 /* Sets default flags for the session */
610 brasero_burn_session_add_flag (BRASERO_BURN_SESSION (priv->session),
611 BRASERO_BURN_FLAG_NOGRACE|
612 BRASERO_BURN_FLAG_CHECK_SIZE);
613
614 /* Create a cancel button */
615 gtk_dialog_add_button (GTK_DIALOG (object),
616 GTK_STOCK_CANCEL,
617 GTK_RESPONSE_CANCEL);
618
619 /* Create an upper box for sources */
620 priv->source_placeholder = gtk_alignment_new (0.0, 0.5, 1.0, 1.0);
621 content_area = gtk_dialog_get_content_area (GTK_DIALOG (object));
622 gtk_box_pack_start (GTK_BOX (content_area),
623 priv->source_placeholder,
624 FALSE,
625 TRUE,
626 0);
627
628 /* Medium selection box */
629 selection = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
630 gtk_widget_show (selection);
631
632 alignment = gtk_alignment_new (0.0, 0.5, 1.0, 1.0);
633 gtk_widget_show (alignment);
634 gtk_box_pack_start (GTK_BOX (selection),
635 alignment,
636 TRUE,
637 TRUE,
638 0);
639
640 priv->selection = brasero_dest_selection_new (BRASERO_BURN_SESSION (priv->session));
641 gtk_widget_show (priv->selection);
642 gtk_container_add (GTK_CONTAINER (alignment), priv->selection);
643
644 priv->properties = brasero_medium_properties_new (priv->session);
645 gtk_size_group_add_widget (priv->size_group, priv->properties);
646 gtk_widget_show (priv->properties);
647 gtk_box_pack_start (GTK_BOX (selection),
648 priv->properties,
649 FALSE,
650 FALSE,
651 0);
652
653 /* Box to display warning messages */
654 priv->message_output = brasero_notify_new ();
655 gtk_widget_show (priv->message_output);
656
657 string = g_strdup_printf ("<b>%s</b>", _("Select a disc to write to"));
658 selection = brasero_utils_pack_properties (string,
659 priv->message_output,
660 selection,
661 NULL);
662 g_free (string);
663 gtk_widget_show (selection);
664
665 gtk_box_pack_start (GTK_BOX (content_area),
666 selection,
667 FALSE,
668 TRUE,
669 0);
670
671 /* Create a lower box for options */
672 alignment = gtk_alignment_new (0.0, 0.5, 1.0, 1.0);
673 gtk_widget_show (alignment);
674 gtk_box_pack_start (GTK_BOX (content_area),
675 alignment,
676 FALSE,
677 TRUE,
678 0);
679 priv->options_placeholder = alignment;
680
681 priv->options = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
682 gtk_container_add (GTK_CONTAINER (alignment), priv->options);
683
684 g_signal_connect (priv->session,
685 "is-valid",
686 G_CALLBACK (brasero_burn_options_valid_cb),
687 object);
688
689 brasero_burn_options_update_valid (object);
690 }
691
692 static void
brasero_burn_options_reset(BraseroBurnOptions * self)693 brasero_burn_options_reset (BraseroBurnOptions *self)
694 {
695 BraseroBurnOptionsPrivate *priv;
696
697 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
698
699 priv->has_image = FALSE;
700 priv->has_audio = FALSE;
701 priv->has_video = FALSE;
702 priv->has_data = FALSE;
703 priv->has_disc = FALSE;
704
705 /* reset all the dialog */
706 if (priv->message_input) {
707 gtk_widget_destroy (priv->message_input);
708 priv->message_input = NULL;
709 }
710
711 if (priv->options) {
712 gtk_widget_destroy (priv->options);
713 priv->options = NULL;
714 }
715
716 priv->options = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
717 gtk_container_add (GTK_CONTAINER (priv->options_placeholder), priv->options);
718
719 if (priv->source) {
720 gtk_widget_destroy (priv->source);
721 priv->source = NULL;
722 }
723
724 gtk_widget_hide (priv->source_placeholder);
725 }
726
727 static void
brasero_burn_options_setup_audio(BraseroBurnOptions * self)728 brasero_burn_options_setup_audio (BraseroBurnOptions *self)
729 {
730 BraseroBurnOptionsPrivate *priv;
731
732 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
733
734 brasero_burn_options_reset (self);
735
736 priv->has_audio = TRUE;
737 gtk_window_set_title (GTK_WINDOW (self), _("Disc Burning Setup"));
738 brasero_burn_options_set_type_shown (BRASERO_BURN_OPTIONS (self),
739 BRASERO_MEDIA_TYPE_WRITABLE|
740 BRASERO_MEDIA_TYPE_FILE);
741 }
742
743 static void
brasero_burn_options_setup_video(BraseroBurnOptions * self)744 brasero_burn_options_setup_video (BraseroBurnOptions *self)
745 {
746 gchar *title;
747 GtkWidget *options;
748 BraseroBurnOptionsPrivate *priv;
749
750 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
751
752 brasero_burn_options_reset (self);
753
754 priv->has_video = TRUE;
755 gtk_window_set_title (GTK_WINDOW (self), _("Disc Burning Setup"));
756 brasero_burn_options_set_type_shown (BRASERO_BURN_OPTIONS (self),
757 BRASERO_MEDIA_TYPE_WRITABLE|
758 BRASERO_MEDIA_TYPE_FILE);
759
760 /* create the options box */
761 options = brasero_video_options_new (BRASERO_BURN_SESSION (priv->session));
762 gtk_widget_show (options);
763
764 title = g_strdup_printf ("<b>%s</b>", _("Video Options"));
765 options = brasero_utils_pack_properties (title,
766 options,
767 NULL);
768 g_free (title);
769
770 gtk_widget_show (options);
771 brasero_burn_options_add_options (self, options);
772 }
773
774 static BraseroBurnResult
brasero_status_dialog_uri_has_image(BraseroTrackDataCfg * track,const gchar * uri,BraseroBurnOptions * self)775 brasero_status_dialog_uri_has_image (BraseroTrackDataCfg *track,
776 const gchar *uri,
777 BraseroBurnOptions *self)
778 {
779 gint answer;
780 gchar *name;
781 GtkWidget *button;
782 GtkWidget *dialog;
783 gboolean was_visible = FALSE;
784 gboolean was_not_ready = FALSE;
785 BraseroTrackImageCfg *track_img;
786 BraseroBurnOptionsPrivate *priv;
787
788 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
789 dialog = gtk_message_dialog_new (GTK_WINDOW (self),
790 GTK_DIALOG_MODAL |
791 GTK_DIALOG_DESTROY_WITH_PARENT,
792 GTK_MESSAGE_QUESTION,
793 GTK_BUTTONS_NONE,
794 "%s",
795 _("Do you want to create a disc from the contents of the image or with the image file inside?"));
796
797 gtk_window_set_title (GTK_WINDOW (dialog), "");
798 gtk_window_set_icon_name (GTK_WINDOW (dialog),
799 gtk_window_get_icon_name (GTK_WINDOW (self)));
800
801 name = brasero_utils_get_uri_name (uri);
802 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
803 /* Translators: %s is the name of the image */
804 _("There is only one selected file (\"%s\"). "
805 "It is the image of a disc and its contents can be burned."),
806 name);
807 g_free (name);
808
809 gtk_dialog_add_button (GTK_DIALOG (dialog), _("Burn as _File"), GTK_RESPONSE_NO);
810
811 button = brasero_utils_make_button (_("Burn _Contents…"),
812 NULL,
813 "media-optical-burn",
814 GTK_ICON_SIZE_BUTTON);
815 gtk_widget_show (button);
816 gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
817 button,
818 GTK_RESPONSE_YES);
819
820 if (!priv->not_ready_id && priv->status_dialog) {
821 was_visible = TRUE;
822 gtk_widget_hide (GTK_WIDGET (priv->status_dialog));
823 }
824 else if (priv->not_ready_id) {
825 g_source_remove (priv->not_ready_id);
826 priv->not_ready_id = 0;
827 was_not_ready = TRUE;
828 }
829
830 gtk_widget_show_all (dialog);
831 answer = gtk_dialog_run (GTK_DIALOG (dialog));
832 gtk_widget_destroy (dialog);
833
834 if (answer != GTK_RESPONSE_YES) {
835 if (was_not_ready)
836 priv->not_ready_id = g_timeout_add_seconds (1,
837 brasero_burn_options_not_ready_dialog_show_cb,
838 self);
839 if (was_visible)
840 gtk_widget_show (GTK_WIDGET (priv->status_dialog));
841
842 return BRASERO_BURN_OK;
843 }
844
845 /* Setup a new track and add it to session */
846 track_img = brasero_track_image_cfg_new ();
847 brasero_track_image_cfg_set_source (track_img, uri);
848 brasero_burn_session_add_track (BRASERO_BURN_SESSION (priv->session),
849 BRASERO_TRACK (track_img),
850 NULL);
851
852 return BRASERO_BURN_CANCEL;
853 }
854
855 static void
brasero_burn_options_setup_data(BraseroBurnOptions * self)856 brasero_burn_options_setup_data (BraseroBurnOptions *self)
857 {
858 GSList *tracks;
859 BraseroBurnOptionsPrivate *priv;
860
861 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
862
863 brasero_burn_options_reset (self);
864
865 /* NOTE: we don't need to keep a record of the signal as the track will
866 * be destroyed if the user agrees to burn the image directly */
867 tracks = brasero_burn_session_get_tracks (BRASERO_BURN_SESSION (priv->session));
868 if (BRASERO_IS_TRACK_DATA_CFG (tracks->data))
869 g_signal_connect (tracks->data,
870 "image-uri",
871 G_CALLBACK (brasero_status_dialog_uri_has_image),
872 self);
873
874 priv->has_data = TRUE;
875 gtk_window_set_title (GTK_WINDOW (self), _("Disc Burning Setup"));
876 brasero_burn_options_set_type_shown (BRASERO_BURN_OPTIONS (self),
877 BRASERO_MEDIA_TYPE_WRITABLE|
878 BRASERO_MEDIA_TYPE_FILE);
879 }
880
881 static void
brasero_burn_options_setup_image(BraseroBurnOptions * self)882 brasero_burn_options_setup_image (BraseroBurnOptions *self)
883 {
884 gchar *string;
885 GtkWidget *file;
886 BraseroBurnOptionsPrivate *priv;
887
888 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
889
890 brasero_burn_options_reset (self);
891
892 priv->has_image = TRUE;
893 gtk_window_set_title (GTK_WINDOW (self), _("Image Burning Setup"));
894 brasero_burn_options_set_type_shown (self, BRASERO_MEDIA_TYPE_WRITABLE);
895
896 /* Image properties */
897 file = brasero_src_image_new (BRASERO_BURN_SESSION (priv->session));
898 gtk_widget_show (file);
899
900 /* pack everything */
901 string = g_strdup_printf ("<b>%s</b>", _("Select a disc image to write"));
902 brasero_burn_options_add_source (self,
903 string,
904 file,
905 NULL);
906 g_free (string);
907 }
908
909 static void
brasero_burn_options_setup_disc(BraseroBurnOptions * self)910 brasero_burn_options_setup_disc (BraseroBurnOptions *self)
911 {
912 gchar *title_str;
913 GtkWidget *source;
914 BraseroBurnOptionsPrivate *priv;
915
916 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
917
918 brasero_burn_options_reset (self);
919
920 priv->has_disc = TRUE;
921 gtk_window_set_title (GTK_WINDOW (self), _("Copy CD/DVD"));
922
923 /* take care of source media */
924 source = brasero_src_selection_new (BRASERO_BURN_SESSION (priv->session));
925 gtk_widget_show (source);
926
927 title_str = g_strdup_printf ("<b>%s</b>", _("Select disc to copy"));
928 brasero_burn_options_add_source (self,
929 title_str,
930 source,
931 NULL);
932 g_free (title_str);
933
934 /* only show media with something to be read on them */
935 brasero_medium_selection_show_media_type (BRASERO_MEDIUM_SELECTION (source),
936 BRASERO_MEDIA_TYPE_AUDIO|
937 BRASERO_MEDIA_TYPE_DATA);
938
939 /* This is a special case. When we're copying, someone may want to read
940 * and burn to the same drive so provided that the drive is a burner
941 * then show its contents. */
942 brasero_burn_options_set_type_shown (self,
943 BRASERO_MEDIA_TYPE_ANY_IN_BURNER|
944 BRASERO_MEDIA_TYPE_FILE);
945 }
946
947 static void
brasero_burn_options_setup(BraseroBurnOptions * self)948 brasero_burn_options_setup (BraseroBurnOptions *self)
949 {
950 BraseroBurnOptionsPrivate *priv;
951 BraseroTrackType *type;
952
953 priv = BRASERO_BURN_OPTIONS_PRIVATE (self);
954
955 /* add the new widgets */
956 type = brasero_track_type_new ();
957 brasero_burn_session_get_input_type (BRASERO_BURN_SESSION (priv->session), type);
958 if (brasero_track_type_get_has_medium (type)) {
959 if (!priv->has_disc)
960 brasero_burn_options_setup_disc (self);
961 }
962 else if (brasero_track_type_get_has_image (type)) {
963 if (!priv->has_image)
964 brasero_burn_options_setup_image (self);
965 }
966 else if (brasero_track_type_get_has_data (type)) {
967 if (!priv->has_data)
968 brasero_burn_options_setup_data (self);
969 }
970 else if (brasero_track_type_get_has_stream (type)) {
971 if (BRASERO_STREAM_FORMAT_HAS_VIDEO (brasero_track_type_get_stream_format (type))) {
972 if (!priv->has_video)
973 brasero_burn_options_setup_video (self);
974 }
975 else if (!priv->has_audio)
976 brasero_burn_options_setup_audio (self);
977 }
978 brasero_track_type_free (type);
979
980 brasero_burn_options_setup_buttons (self);
981 }
982
983 static void
brasero_burn_options_track_added(BraseroBurnSession * session,BraseroTrack * track,BraseroBurnOptions * dialog)984 brasero_burn_options_track_added (BraseroBurnSession *session,
985 BraseroTrack *track,
986 BraseroBurnOptions *dialog)
987 {
988 brasero_burn_options_setup (dialog);
989 }
990
991 static void
brasero_burn_options_track_removed(BraseroBurnSession * session,BraseroTrack * track,guint former_position,BraseroBurnOptions * dialog)992 brasero_burn_options_track_removed (BraseroBurnSession *session,
993 BraseroTrack *track,
994 guint former_position,
995 BraseroBurnOptions *dialog)
996 {
997 brasero_burn_options_setup (dialog);
998 }
999
1000 static void
brasero_burn_options_track_changed(BraseroBurnSession * session,BraseroTrack * track,BraseroBurnOptions * dialog)1001 brasero_burn_options_track_changed (BraseroBurnSession *session,
1002 BraseroTrack *track,
1003 BraseroBurnOptions *dialog)
1004 {
1005 brasero_burn_options_setup (dialog);
1006 }
1007
1008 static void
brasero_burn_options_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)1009 brasero_burn_options_set_property (GObject *object,
1010 guint prop_id,
1011 const GValue *value,
1012 GParamSpec *pspec)
1013 {
1014 BraseroBurnOptionsPrivate *priv;
1015
1016 g_return_if_fail (BRASERO_IS_BURN_OPTIONS (object));
1017
1018 priv = BRASERO_BURN_OPTIONS_PRIVATE (object);
1019
1020 switch (prop_id)
1021 {
1022 case PROP_SESSION: /* Readable and only writable at creation time */
1023 priv->session = g_object_ref (g_value_get_object (value));
1024
1025 g_object_notify (object, "session");
1026
1027 g_signal_connect (priv->session,
1028 "track-added",
1029 G_CALLBACK (brasero_burn_options_track_added),
1030 object);
1031 g_signal_connect (priv->session,
1032 "track-removed",
1033 G_CALLBACK (brasero_burn_options_track_removed),
1034 object);
1035 g_signal_connect (priv->session,
1036 "track-changed",
1037 G_CALLBACK (brasero_burn_options_track_changed),
1038 object);
1039 brasero_burn_options_build_contents (BRASERO_BURN_OPTIONS (object));
1040 brasero_burn_options_setup (BRASERO_BURN_OPTIONS (object));
1041
1042 break;
1043 default:
1044 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1045 break;
1046 }
1047 }
1048
1049 static void
brasero_burn_options_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)1050 brasero_burn_options_get_property (GObject *object,
1051 guint prop_id,
1052 GValue *value,
1053 GParamSpec *pspec)
1054 {
1055 BraseroBurnOptionsPrivate *priv;
1056
1057 g_return_if_fail (BRASERO_IS_BURN_OPTIONS (object));
1058
1059 priv = BRASERO_BURN_OPTIONS_PRIVATE (object);
1060
1061 switch (prop_id)
1062 {
1063 case PROP_SESSION:
1064 g_value_set_object (value, priv->session);
1065 g_object_ref (priv->session);
1066 break;
1067 default:
1068 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1069 break;
1070 }
1071 }
1072
1073 static void
brasero_burn_options_finalize(GObject * object)1074 brasero_burn_options_finalize (GObject *object)
1075 {
1076 BraseroBurnOptionsPrivate *priv;
1077
1078 priv = BRASERO_BURN_OPTIONS_PRIVATE (object);
1079
1080 if (priv->cancel) {
1081 g_cancellable_cancel (priv->cancel);
1082 priv->cancel = NULL;
1083 }
1084
1085 if (priv->not_ready_id) {
1086 g_source_remove (priv->not_ready_id);
1087 priv->not_ready_id = 0;
1088 }
1089
1090 if (priv->status_dialog) {
1091 gtk_widget_destroy (priv->status_dialog);
1092 priv->status_dialog = NULL;
1093 }
1094
1095 if (priv->session) {
1096 g_signal_handlers_disconnect_by_func (priv->session,
1097 brasero_burn_options_track_added,
1098 object);
1099 g_signal_handlers_disconnect_by_func (priv->session,
1100 brasero_burn_options_track_removed,
1101 object);
1102 g_signal_handlers_disconnect_by_func (priv->session,
1103 brasero_burn_options_track_changed,
1104 object);
1105 g_signal_handlers_disconnect_by_func (priv->session,
1106 brasero_burn_options_valid_cb,
1107 object);
1108
1109 g_object_unref (priv->session);
1110 priv->session = NULL;
1111 }
1112
1113 if (priv->size_group) {
1114 g_object_unref (priv->size_group);
1115 priv->size_group = NULL;
1116 }
1117
1118 G_OBJECT_CLASS (brasero_burn_options_parent_class)->finalize (object);
1119 }
1120
1121 static BraseroBurnResult
brasero_burn_options_install_missing(BraseroPluginErrorType type,const gchar * detail,gpointer user_data)1122 brasero_burn_options_install_missing (BraseroPluginErrorType type,
1123 const gchar *detail,
1124 gpointer user_data)
1125 {
1126 BraseroBurnOptionsPrivate *priv = BRASERO_BURN_OPTIONS_PRIVATE (user_data);
1127 GCancellable *cancel;
1128 BraseroPK *package;
1129 gboolean res;
1130 int xid = 0;
1131
1132 /* Get the xid */
1133 xid = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (user_data)));
1134
1135 package = brasero_pk_new ();
1136 cancel = g_cancellable_new ();
1137 priv->cancel = cancel;
1138 switch (type) {
1139 case BRASERO_PLUGIN_ERROR_MISSING_APP:
1140 res = brasero_pk_install_missing_app (package, detail, xid, cancel);
1141 break;
1142
1143 case BRASERO_PLUGIN_ERROR_MISSING_LIBRARY:
1144 res = brasero_pk_install_missing_library (package, detail, xid, cancel);
1145 break;
1146
1147 case BRASERO_PLUGIN_ERROR_MISSING_GSTREAMER_PLUGIN:
1148 res = brasero_pk_install_gstreamer_plugin (package, detail, xid, cancel);
1149 break;
1150
1151 default:
1152 res = FALSE;
1153 break;
1154 }
1155
1156 if (package) {
1157 g_object_unref (package);
1158 package = NULL;
1159 }
1160
1161 if (g_cancellable_is_cancelled (cancel)) {
1162 g_object_unref (cancel);
1163 return BRASERO_BURN_CANCEL;
1164 }
1165
1166 priv->cancel = NULL;
1167 g_object_unref (cancel);
1168
1169 if (!res)
1170 return BRASERO_BURN_ERR;
1171
1172 return BRASERO_BURN_RETRY;
1173 }
1174
1175 static BraseroBurnResult
brasero_burn_options_list_missing(BraseroPluginErrorType type,const gchar * detail,gpointer user_data)1176 brasero_burn_options_list_missing (BraseroPluginErrorType type,
1177 const gchar *detail,
1178 gpointer user_data)
1179 {
1180 GString *string = user_data;
1181
1182 if (type == BRASERO_PLUGIN_ERROR_MISSING_APP ||
1183 type == BRASERO_PLUGIN_ERROR_SYMBOLIC_LINK_APP ||
1184 type == BRASERO_PLUGIN_ERROR_WRONG_APP_VERSION) {
1185 g_string_append_c (string, '\n');
1186 /* Translators: %s is the name of a missing application */
1187 g_string_append_printf (string, _("%s (application)"), detail);
1188 }
1189 else if (type == BRASERO_PLUGIN_ERROR_MISSING_LIBRARY ||
1190 type == BRASERO_PLUGIN_ERROR_LIBRARY_VERSION) {
1191 g_string_append_c (string, '\n');
1192 /* Translators: %s is the name of a missing library */
1193 g_string_append_printf (string, _("%s (library)"), detail);
1194 }
1195 else if (type == BRASERO_PLUGIN_ERROR_MISSING_GSTREAMER_PLUGIN) {
1196 g_string_append_c (string, '\n');
1197 /* Translators: %s is the name of a missing GStreamer plugin */
1198 g_string_append_printf (string, _("%s (GStreamer plugin)"), detail);
1199 }
1200
1201 return BRASERO_BURN_OK;
1202 }
1203
1204 static void
brasero_burn_options_response(GtkDialog * dialog,GtkResponseType response)1205 brasero_burn_options_response (GtkDialog *dialog,
1206 GtkResponseType response)
1207 {
1208 BraseroBurnOptionsPrivate *priv;
1209 BraseroBurnResult result;
1210 GString *string;
1211
1212 if (response != GTK_RESPONSE_OK)
1213 return;
1214
1215 priv = BRASERO_BURN_OPTIONS_PRIVATE (dialog);
1216 gtk_widget_set_sensitive (GTK_WIDGET (dialog), FALSE);
1217
1218 result = brasero_session_foreach_plugin_error (BRASERO_BURN_SESSION (priv->session),
1219 brasero_burn_options_install_missing,
1220 dialog);
1221 if (result == BRASERO_BURN_CANCEL)
1222 return;
1223
1224 gtk_widget_set_sensitive (GTK_WIDGET (dialog), TRUE);
1225
1226 if (result == BRASERO_BURN_OK)
1227 return;
1228
1229 string = g_string_new (_("Please install the following manually and try again:"));
1230 brasero_session_foreach_plugin_error (BRASERO_BURN_SESSION (priv->session),
1231 brasero_burn_options_list_missing,
1232 string);
1233
1234 brasero_utils_message_dialog (GTK_WIDGET (dialog),
1235 _("All required applications and libraries are not installed."),
1236 string->str,
1237 GTK_MESSAGE_ERROR);
1238 g_string_free (string, TRUE);
1239
1240 /* Cancel the rest */
1241 gtk_dialog_response (dialog, GTK_RESPONSE_CANCEL);
1242 }
1243
1244 static void
brasero_burn_options_class_init(BraseroBurnOptionsClass * klass)1245 brasero_burn_options_class_init (BraseroBurnOptionsClass *klass)
1246 {
1247 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1248 GtkDialogClass *gtk_dialog_class = GTK_DIALOG_CLASS (klass);
1249
1250 g_type_class_add_private (klass, sizeof (BraseroBurnOptionsPrivate));
1251
1252 object_class->finalize = brasero_burn_options_finalize;
1253 object_class->set_property = brasero_burn_options_set_property;
1254 object_class->get_property = brasero_burn_options_get_property;
1255
1256 gtk_dialog_class->response = brasero_burn_options_response;
1257
1258 g_object_class_install_property (object_class,
1259 PROP_SESSION,
1260 g_param_spec_object ("session",
1261 "The session",
1262 "The session to work with",
1263 BRASERO_TYPE_BURN_SESSION,
1264 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
1265 }
1266
1267 /**
1268 * brasero_burn_options_new:
1269 * @session: a #BraseroSessionCfg object
1270 *
1271 * Creates a new #BraseroBurnOptions object.
1272 *
1273 * Return value: a #GtkWidget object.
1274 **/
1275
1276 GtkWidget *
brasero_burn_options_new(BraseroSessionCfg * session)1277 brasero_burn_options_new (BraseroSessionCfg *session)
1278 {
1279 return g_object_new (BRASERO_TYPE_BURN_OPTIONS, "session", session, NULL);
1280 }
1281