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 <string.h>
36
37 #include <glib.h>
38 #include <glib-object.h>
39 #include <glib/gi18n-lib.h>
40
41 #include <gio/gio.h>
42
43 #include <gtk/gtk.h>
44
45 #include "brasero-medium.h"
46 #include "brasero-drive.h"
47
48 #include "brasero-misc.h"
49
50 #include "burn-basics.h"
51 #include "burn-debug.h"
52 #include "brasero-drive-properties.h"
53
54 typedef struct _BraseroDrivePropertiesPrivate BraseroDrivePropertiesPrivate;
55 struct _BraseroDrivePropertiesPrivate
56 {
57 BraseroSessionCfg *session;
58 gulong valid_sig;
59 gulong output_sig;
60
61 GtkWidget *speed;
62 GtkWidget *dummy;
63 GtkWidget *multi;
64 GtkWidget *burnproof;
65 GtkWidget *notmp;
66
67 GtkWidget *tmpdir;
68 };
69
70 #define BRASERO_DRIVE_PROPERTIES_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_DRIVE_PROPERTIES, BraseroDrivePropertiesPrivate))
71
72 enum {
73 TEXT_COL,
74 RATE_COL,
75 COL_NUM
76 };
77
78 enum {
79 PROP_0,
80 PROP_SESSION
81 };
82
83 G_DEFINE_TYPE (BraseroDriveProperties, brasero_drive_properties, GTK_TYPE_ALIGNMENT);
84
85 static void
brasero_drive_properties_no_tmp_toggled(GtkToggleButton * button,BraseroDriveProperties * self)86 brasero_drive_properties_no_tmp_toggled (GtkToggleButton *button,
87 BraseroDriveProperties *self)
88 {
89 BraseroDrivePropertiesPrivate *priv;
90
91 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
92
93 /* retrieve the flags */
94 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->notmp)))
95 brasero_session_cfg_add_flags (priv->session,
96 BRASERO_BURN_FLAG_NO_TMP_FILES);
97 else
98 brasero_session_cfg_remove_flags (priv->session,
99 BRASERO_BURN_FLAG_NO_TMP_FILES);
100 }
101
102 static void
brasero_drive_properties_dummy_toggled(GtkToggleButton * button,BraseroDriveProperties * self)103 brasero_drive_properties_dummy_toggled (GtkToggleButton *button,
104 BraseroDriveProperties *self)
105 {
106 BraseroDrivePropertiesPrivate *priv;
107
108 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
109
110 /* retrieve the flags */
111 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->dummy)))
112 brasero_session_cfg_add_flags (priv->session,
113 BRASERO_BURN_FLAG_DUMMY);
114 else
115 brasero_session_cfg_remove_flags (priv->session,
116 BRASERO_BURN_FLAG_DUMMY);
117 }
118
119 static void
brasero_drive_properties_burnproof_toggled(GtkToggleButton * button,BraseroDriveProperties * self)120 brasero_drive_properties_burnproof_toggled (GtkToggleButton *button,
121 BraseroDriveProperties *self)
122 {
123 BraseroDrivePropertiesPrivate *priv;
124
125 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
126
127 /* retrieve the flags */
128 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->burnproof)))
129 brasero_session_cfg_add_flags (priv->session,
130 BRASERO_BURN_FLAG_BURNPROOF);
131 else
132 brasero_session_cfg_remove_flags (priv->session,
133 BRASERO_BURN_FLAG_BURNPROOF);
134 }
135
136 static void
brasero_drive_properties_multi_toggled(GtkToggleButton * button,BraseroDriveProperties * self)137 brasero_drive_properties_multi_toggled (GtkToggleButton *button,
138 BraseroDriveProperties *self)
139 {
140 BraseroDrivePropertiesPrivate *priv;
141
142 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
143
144 /* retrieve the flags */
145 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->multi)))
146 brasero_session_cfg_add_flags (priv->session,
147 BRASERO_BURN_FLAG_MULTI);
148 else
149 brasero_session_cfg_remove_flags (priv->session,
150 BRASERO_BURN_FLAG_MULTI);
151 }
152
153 static void
brasero_drive_properties_set_tmpdir_info(BraseroDriveProperties * self,const gchar * path)154 brasero_drive_properties_set_tmpdir_info (BraseroDriveProperties *self,
155 const gchar *path)
156 {
157 GFile *file;
158 gchar *string;
159 GFileInfo *info;
160 gchar *string_size;
161 guint64 vol_size = 0;
162 BraseroDrivePropertiesPrivate *priv;
163
164 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
165
166 /* get the volume free space */
167 file = g_file_new_for_commandline_arg (path);
168 if (!file) {
169 BRASERO_BURN_LOG ("Impossible to retrieve size for %s", path);
170 gtk_label_set_text (GTK_LABEL (priv->tmpdir), path);
171 return;
172 }
173
174 info = g_file_query_filesystem_info (file,
175 G_FILE_ATTRIBUTE_FILESYSTEM_FREE,
176 NULL,
177 NULL);
178 g_object_unref (file);
179
180 if (!info) {
181 BRASERO_BURN_LOG ("Impossible to retrieve size for %s", path);
182 gtk_label_set_text (GTK_LABEL (priv->tmpdir), path);
183 return;
184 }
185
186 vol_size = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
187 g_object_unref (info);
188
189 string_size = g_format_size (vol_size);
190 /* Translators: the first %s is the path of the directory where brasero
191 * will store its temporary files; the second one is the size available */
192 string = g_strdup_printf (_("%s: %s free"), path, string_size);
193 g_free (string_size);
194
195 gtk_label_set_text (GTK_LABEL (priv->tmpdir), string);
196 g_free (string);
197 }
198
199 static gboolean
brasero_drive_properties_check_tmpdir(BraseroDriveProperties * self,const gchar * path)200 brasero_drive_properties_check_tmpdir (BraseroDriveProperties *self,
201 const gchar *path)
202 {
203 GFile *file;
204 GFileInfo *info;
205 GError *error = NULL;
206 const gchar *filesystem;
207
208 file = g_file_new_for_commandline_arg (path);
209 if (!file)
210 return TRUE;
211
212 info = g_file_query_info (file,
213 G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
214 G_FILE_QUERY_INFO_NONE,
215 NULL,
216 &error);
217 if (error) {
218 gint answer;
219 gchar *string;
220 GtkWidget *dialog;
221 GtkWidget *toplevel;
222
223 if (error)
224 return TRUE;
225
226 /* Tell the user what went wrong */
227 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
228 dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel),
229 GTK_DIALOG_DESTROY_WITH_PARENT |
230 GTK_DIALOG_MODAL,
231 GTK_MESSAGE_WARNING,
232 GTK_BUTTONS_NONE,
233 _("Do you really want to choose this location?"));
234
235 gtk_window_set_icon_name (GTK_WINDOW (dialog),
236 gtk_window_get_icon_name (GTK_WINDOW (toplevel)));
237
238 string = g_strdup_printf ("%s.", error->message);
239 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", string);
240 g_error_free (error);
241 g_free (string);
242
243 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
244 _("_Keep Current Location"), GTK_RESPONSE_CANCEL,
245 _("_Change Location"), GTK_RESPONSE_OK,
246 NULL);
247
248 gtk_widget_show_all (dialog);
249 answer = gtk_dialog_run (GTK_DIALOG (dialog));
250 gtk_widget_destroy (dialog);
251
252 g_object_unref (info);
253 g_object_unref (file);
254 if (answer != GTK_RESPONSE_OK)
255 return TRUE;
256
257 return FALSE;
258 }
259
260 if (!g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) {
261 gint answer;
262 gchar *string;
263 GtkWidget *dialog;
264 GtkWidget *toplevel;
265
266 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
267 dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel),
268 GTK_DIALOG_DESTROY_WITH_PARENT |
269 GTK_DIALOG_MODAL,
270 GTK_MESSAGE_WARNING,
271 GTK_BUTTONS_NONE,
272 _("Do you really want to choose this location?"));
273
274 gtk_window_set_icon_name (GTK_WINDOW (dialog),
275 gtk_window_get_icon_name (GTK_WINDOW (toplevel)));
276
277 string = g_strdup_printf ("%s.", _("You do not have the required permission to write at this location"));
278 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", string);
279 g_free (string);
280
281 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
282 _("_Keep Current Location"), GTK_RESPONSE_CANCEL,
283 _("_Change Location"), GTK_RESPONSE_OK,
284 NULL);
285
286 gtk_widget_show_all (dialog);
287 answer = gtk_dialog_run (GTK_DIALOG (dialog));
288 gtk_widget_destroy (dialog);
289
290 g_object_unref (info);
291 g_object_unref (file);
292 if (answer != GTK_RESPONSE_OK)
293 return TRUE;
294
295 return FALSE;
296 }
297
298 g_object_unref (info);
299 info = g_file_query_filesystem_info (file,
300 G_FILE_ATTRIBUTE_FILESYSTEM_TYPE,
301 NULL,
302 &error);
303 g_object_unref (file);
304
305 /* NOTE/FIXME: also check, probably best at start or in a special dialog
306 * whether quotas or any other limitation enforced on the system may not
307 * get in out way. Think getrlimit (). */
308
309 /* check the filesystem type: the problem here is that some
310 * filesystems have a maximum file size limit of 4 GiB and more than
311 * often we need a temporary file size of 4 GiB or more. */
312 filesystem = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE);
313 if (!g_strcmp0 (filesystem, "msdos")) {
314 gint answer;
315 GtkWidget *dialog;
316 GtkWidget *toplevel;
317
318 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
319 dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel),
320 GTK_DIALOG_DESTROY_WITH_PARENT |
321 GTK_DIALOG_MODAL,
322 GTK_MESSAGE_WARNING,
323 GTK_BUTTONS_NONE,
324 _("Do you really want to choose this location?"));
325
326 gtk_window_set_icon_name (GTK_WINDOW (dialog),
327 gtk_window_get_icon_name (GTK_WINDOW (toplevel)));
328
329 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
330 _("The filesystem on this volume does not support large files (size over 2 GiB)."
331 "\nThis can be a problem when writing DVDs or large images."));
332
333 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
334 _("_Keep Current Location"), GTK_RESPONSE_CANCEL,
335 _("_Change Location"), GTK_RESPONSE_OK,
336 NULL);
337
338 gtk_widget_show_all (dialog);
339 answer = gtk_dialog_run (GTK_DIALOG (dialog));
340 gtk_widget_destroy (dialog);
341
342 g_object_unref (info);
343 if (answer != GTK_RESPONSE_OK)
344 return TRUE;
345 }
346 else if (info)
347 g_object_unref (info);
348
349 return FALSE;
350 }
351
352 static void
brasero_drive_properties_tmpdir_clicked(GtkButton * button,BraseroDriveProperties * self)353 brasero_drive_properties_tmpdir_clicked (GtkButton *button,
354 BraseroDriveProperties *self)
355 {
356 GtkWidget *parent;
357 const gchar *path;
358 GtkWidget *chooser;
359 GtkResponseType res;
360 const gchar *new_path;
361 BraseroDrivePropertiesPrivate *priv;
362
363 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
364
365 parent = gtk_widget_get_toplevel (GTK_WIDGET (button));
366 chooser = gtk_file_chooser_dialog_new (_("Location for Temporary Files"),
367 GTK_WINDOW (parent),
368 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
369 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
370 GTK_STOCK_OK, GTK_RESPONSE_OK,
371 NULL);
372
373 path = brasero_burn_session_get_tmpdir (BRASERO_BURN_SESSION (priv->session));
374 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (chooser), path);
375 res = gtk_dialog_run (GTK_DIALOG (chooser));
376 if (res != GTK_RESPONSE_OK) {
377 gtk_widget_destroy (chooser);
378 return;
379 }
380
381 new_path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
382 if (!new_path || !strcmp (new_path, path)) {
383 gtk_widget_destroy (chooser);
384 return;
385 }
386
387 if (!brasero_drive_properties_check_tmpdir (self, new_path)) {
388 brasero_burn_session_set_tmpdir (BRASERO_BURN_SESSION (priv->session), new_path);
389 brasero_drive_properties_set_tmpdir_info (self, new_path);
390 }
391
392 gtk_widget_destroy (chooser);
393 }
394
395 static void
brasero_drive_properties_set_tmpdir(BraseroDriveProperties * self,const gchar * path)396 brasero_drive_properties_set_tmpdir (BraseroDriveProperties *self,
397 const gchar *path)
398 {
399 if (!path)
400 path = g_get_tmp_dir ();
401
402 brasero_drive_properties_set_tmpdir_info (self, path);
403 }
404
405 static void
406 brasero_drive_properties_set_flags (BraseroDriveProperties *self,
407 BraseroBurnFlag flags,
408 BraseroBurnFlag supported,
409 BraseroBurnFlag compulsory);
410
411 static void
brasero_drive_properties_set_toggle_state(BraseroDriveProperties * self,GtkWidget * toggle,BraseroBurnFlag flag,BraseroBurnFlag flags,BraseroBurnFlag supported,BraseroBurnFlag compulsory)412 brasero_drive_properties_set_toggle_state (BraseroDriveProperties *self,
413 GtkWidget *toggle,
414 BraseroBurnFlag flag,
415 BraseroBurnFlag flags,
416 BraseroBurnFlag supported,
417 BraseroBurnFlag compulsory)
418 {
419 if (!(supported & flag)) {
420 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), FALSE);
421 gtk_widget_set_sensitive (toggle, FALSE);
422 gtk_widget_hide (toggle);
423 return;
424 }
425
426 gtk_widget_show (toggle);
427 g_signal_handlers_block_by_func (toggle,
428 brasero_drive_properties_set_flags,
429 self);
430 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), (flags & flag));
431 g_signal_handlers_unblock_by_func (toggle,
432 brasero_drive_properties_set_flags,
433 self);
434
435 gtk_widget_set_sensitive (toggle, (compulsory & flag) == 0);
436 }
437
438 static void
brasero_drive_properties_set_flags(BraseroDriveProperties * self,BraseroBurnFlag flags,BraseroBurnFlag supported,BraseroBurnFlag compulsory)439 brasero_drive_properties_set_flags (BraseroDriveProperties *self,
440 BraseroBurnFlag flags,
441 BraseroBurnFlag supported,
442 BraseroBurnFlag compulsory)
443 {
444 BraseroDrivePropertiesPrivate *priv;
445
446 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
447
448 flags &= BRASERO_DRIVE_PROPERTIES_FLAGS;
449 supported &= BRASERO_DRIVE_PROPERTIES_FLAGS;
450 compulsory &= BRASERO_DRIVE_PROPERTIES_FLAGS;
451
452 /* flag properties */
453 brasero_drive_properties_set_toggle_state (self,
454 priv->dummy,
455 BRASERO_BURN_FLAG_DUMMY,
456 flags,
457 supported,
458 compulsory);
459 brasero_drive_properties_set_toggle_state (self,
460 priv->burnproof,
461 BRASERO_BURN_FLAG_BURNPROOF,
462 flags,
463 supported,
464 compulsory);
465 brasero_drive_properties_set_toggle_state (self,
466 priv->notmp,
467 BRASERO_BURN_FLAG_NO_TMP_FILES,
468 flags,
469 supported,
470 compulsory);
471 brasero_drive_properties_set_toggle_state (self,
472 priv->multi,
473 BRASERO_BURN_FLAG_MULTI,
474 flags,
475 supported,
476 compulsory);
477 }
478
479 static gint64
brasero_drive_properties_get_rate(BraseroDriveProperties * self)480 brasero_drive_properties_get_rate (BraseroDriveProperties *self)
481 {
482 BraseroDrivePropertiesPrivate *priv;
483 GtkTreeModel *model;
484 GtkTreeIter iter;
485 gint64 rate;
486
487 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
488
489 model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->speed));
490 if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->speed), &iter)
491 && !gtk_tree_model_get_iter_first (model, &iter))
492 return 0;
493
494 gtk_tree_model_get (model, &iter,
495 RATE_COL, &rate,
496 -1);
497 return rate;
498 }
499
500 static void
brasero_drive_properties_rate_changed_cb(GtkComboBox * combo,BraseroDriveProperties * self)501 brasero_drive_properties_rate_changed_cb (GtkComboBox *combo,
502 BraseroDriveProperties *self)
503 {
504 BraseroDrivePropertiesPrivate *priv;
505 guint64 rate;
506
507 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
508
509 rate = brasero_drive_properties_get_rate (self);
510 if (!rate)
511 return;
512
513 brasero_burn_session_set_rate (BRASERO_BURN_SESSION (priv->session), rate);
514 }
515
516 static gchar *
brasero_drive_properties_format_disc_speed(BraseroMedia media,gint64 rate)517 brasero_drive_properties_format_disc_speed (BraseroMedia media,
518 gint64 rate)
519 {
520 gchar *text;
521
522 if (media & BRASERO_MEDIUM_DVD)
523 /* Translators %s.1f is the speed used to burn */
524 text = g_strdup_printf (_("%.1f\303\227 (DVD)"),
525 BRASERO_RATE_TO_SPEED_DVD (rate));
526 else if (media & BRASERO_MEDIUM_CD)
527 /* Translators %s.1f is the speed used to burn */
528 text = g_strdup_printf (_("%.1f\303\227 (CD)"),
529 BRASERO_RATE_TO_SPEED_CD (rate));
530 else if (media & BRASERO_MEDIUM_BD)
531 /* Translators %s.1f is the speed used to burn. BD = Blu Ray*/
532 text = g_strdup_printf (_("%.1f\303\227 (BD)"),
533 BRASERO_RATE_TO_SPEED_BD (rate));
534 else
535 /* Translators %s.1f is the speed used to burn for every medium
536 * type. BD = Blu Ray*/
537 text = g_strdup_printf (_("%.1f\303\227 (BD) %.1f\303\227 (DVD) %.1f\303\227 (CD)"),
538 BRASERO_RATE_TO_SPEED_BD (rate),
539 BRASERO_RATE_TO_SPEED_DVD (rate),
540 BRASERO_RATE_TO_SPEED_CD (rate));
541
542 return text;
543 }
544
545 static void
brasero_drive_properties_set_drive(BraseroDriveProperties * self,BraseroDrive * drive,gint64 default_rate)546 brasero_drive_properties_set_drive (BraseroDriveProperties *self,
547 BraseroDrive *drive,
548 gint64 default_rate)
549 {
550 BraseroDrivePropertiesPrivate *priv;
551 BraseroMedium *medium;
552 BraseroMedia media;
553 GtkTreeModel *model;
554 GtkTreeIter iter;
555 guint64 *rates;
556 gchar *text;
557 guint i;
558
559 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
560
561 /* Speed combo */
562 medium = brasero_drive_get_medium (drive);
563 media = brasero_medium_get_status (medium);
564 if (media & BRASERO_MEDIUM_FILE)
565 return;
566
567 rates = brasero_medium_get_write_speeds (medium);
568 model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->speed));
569 gtk_list_store_clear (GTK_LIST_STORE (model));
570
571 if (!rates) {
572 gtk_widget_set_sensitive (priv->speed, FALSE);
573 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
574 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
575 TEXT_COL, _("Impossible to retrieve speeds"),
576 RATE_COL, 1764, /* Speed 1 */
577 -1);
578 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->speed), &iter);
579 return;
580 }
581
582 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
583 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
584 TEXT_COL, _("Maximum speed"),
585 RATE_COL, rates [0],
586 -1);
587
588 /* fill model */
589 for (i = 0; rates [i] != 0; i ++) {
590 text = brasero_drive_properties_format_disc_speed (media, rates [i]);
591 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
592 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
593 TEXT_COL, text,
594 RATE_COL, rates [i],
595 -1);
596 g_free (text);
597 }
598 g_free (rates);
599
600 /* Set active one preferably max speed */
601 gtk_tree_model_get_iter_first (model, &iter);
602 do {
603 gint64 rate;
604
605 gtk_tree_model_get (model, &iter,
606 RATE_COL, &rate,
607 -1);
608
609 /* we do this to round things and get the closest possible speed */
610 if ((rate / 1024) == (default_rate / 1024)) {
611 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->speed), &iter);
612 break;
613 }
614
615 } while (gtk_tree_model_iter_next (model, &iter));
616
617 /* make sure at least one is active */
618 if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->speed), &iter)) {
619 gtk_tree_model_get_iter_first (model, &iter);
620 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->speed), &iter);
621 }
622 }
623
624 static void
brasero_drive_properties_update(BraseroDriveProperties * self)625 brasero_drive_properties_update (BraseroDriveProperties *self)
626 {
627 BraseroBurnFlag compulsory = BRASERO_BURN_FLAG_NONE;
628 BraseroBurnFlag supported = BRASERO_BURN_FLAG_NONE;
629 BraseroDrivePropertiesPrivate *priv;
630 BraseroBurnFlag flags;
631
632 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
633 brasero_drive_properties_set_drive (self,
634 brasero_burn_session_get_burner (BRASERO_BURN_SESSION (priv->session)),
635 brasero_burn_session_get_rate (BRASERO_BURN_SESSION (priv->session)));
636
637 flags = brasero_burn_session_get_flags (BRASERO_BURN_SESSION (priv->session));
638 brasero_burn_session_get_burn_flags (BRASERO_BURN_SESSION (priv->session),
639 &supported,
640 &compulsory);
641 brasero_drive_properties_set_flags (self,
642 flags,
643 supported,
644 compulsory);
645 brasero_drive_properties_set_tmpdir (self, brasero_burn_session_get_tmpdir (BRASERO_BURN_SESSION (priv->session)));
646 }
647
648 static void
brasero_drive_properties_is_valid_cb(BraseroSessionCfg * session,BraseroDriveProperties * self)649 brasero_drive_properties_is_valid_cb (BraseroSessionCfg *session,
650 BraseroDriveProperties *self)
651 {
652 BraseroDrivePropertiesPrivate *priv;
653 BraseroBurnFlag compulsory;
654 BraseroBurnFlag supported;
655 BraseroBurnFlag flags;
656
657 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
658
659 flags = brasero_burn_session_get_flags (BRASERO_BURN_SESSION (priv->session));
660 brasero_burn_session_get_burn_flags (BRASERO_BURN_SESSION (priv->session),
661 &supported,
662 &compulsory);
663 brasero_drive_properties_set_flags (self,
664 flags,
665 supported,
666 compulsory);
667 }
668
669 static void
brasero_drive_properties_output_changed_cb(BraseroSessionCfg * session,BraseroMedium * former,BraseroDriveProperties * self)670 brasero_drive_properties_output_changed_cb (BraseroSessionCfg *session,
671 BraseroMedium *former,
672 BraseroDriveProperties *self)
673 {
674 BraseroDrivePropertiesPrivate *priv;
675
676 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (self);
677
678 /* if the drive changed update rate but only if the drive changed that's
679 * why we don't do it when the is-valid signal is emitted. */
680 brasero_drive_properties_set_drive (self,
681 brasero_burn_session_get_burner (BRASERO_BURN_SESSION (priv->session)),
682 brasero_burn_session_get_rate (BRASERO_BURN_SESSION (priv->session)));
683 }
684
685 static void
brasero_drive_properties_init(BraseroDriveProperties * object)686 brasero_drive_properties_init (BraseroDriveProperties *object)
687 {
688 BraseroDrivePropertiesPrivate *priv;
689 GtkCellRenderer *renderer;
690 GtkTreeModel *model;
691 GtkWidget *button;
692 GtkWidget *image;
693 GtkWidget *label;
694 GtkWidget *vbox;
695 GtkWidget *box;
696 gchar *string;
697
698 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (object);
699
700 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
701 gtk_widget_show (vbox);
702 gtk_container_add (GTK_CONTAINER (object), vbox);
703
704 model = GTK_TREE_MODEL (gtk_list_store_new (COL_NUM,
705 G_TYPE_STRING,
706 G_TYPE_INT64));
707
708 priv->speed = gtk_combo_box_new_with_model (model);
709 gtk_widget_show (priv->speed);
710 string = g_strdup_printf ("<b>%s</b>", _("Burning speed"));
711 gtk_box_pack_start (GTK_BOX (vbox),
712 brasero_utils_pack_properties (string,
713 priv->speed, NULL),
714 FALSE, FALSE, 0);
715 g_free (string);
716
717 renderer = gtk_cell_renderer_text_new ();
718 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->speed), renderer, TRUE);
719 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->speed), renderer,
720 "text", TEXT_COL,
721 NULL);
722
723 priv->dummy = gtk_check_button_new_with_mnemonic (_("_Simulate before burning"));
724 gtk_widget_set_tooltip_text (priv->dummy, _("Brasero will simulate the burning and, if it is successful, go on with actual burning after 10 seconds"));
725 gtk_widget_show (priv->dummy);
726 priv->burnproof = gtk_check_button_new_with_mnemonic (_("Use burn_proof (decrease the risk of failures)"));
727 gtk_widget_show (priv->burnproof);
728 priv->notmp = gtk_check_button_new_with_mnemonic (_("Burn the image directly _without saving it to disc"));
729 gtk_widget_show (priv->notmp);
730 priv->multi = gtk_check_button_new_with_mnemonic (_("Leave the disc _open to add other files later"));
731 gtk_widget_set_tooltip_text (priv->multi, _("Allow to add more data to the disc later"));
732 gtk_widget_show (priv->multi);
733
734 g_signal_connect (priv->dummy,
735 "toggled",
736 G_CALLBACK (brasero_drive_properties_dummy_toggled),
737 object);
738 g_signal_connect (priv->burnproof,
739 "toggled",
740 G_CALLBACK (brasero_drive_properties_burnproof_toggled),
741 object);
742 g_signal_connect (priv->multi,
743 "toggled",
744 G_CALLBACK (brasero_drive_properties_multi_toggled),
745 object);
746 g_signal_connect (priv->notmp,
747 "toggled",
748 G_CALLBACK (brasero_drive_properties_no_tmp_toggled),
749 object);
750
751 string = g_strdup_printf ("<b>%s</b>", _("Options"));
752 gtk_box_pack_start (GTK_BOX (vbox),
753 brasero_utils_pack_properties (string,
754 priv->dummy,
755 priv->burnproof,
756 priv->multi,
757 priv->notmp,
758 NULL),
759 FALSE,
760 FALSE, 0);
761 g_free (string);
762
763 label = gtk_label_new_with_mnemonic (_("Location for _Temporary Files"));
764 gtk_widget_show (label);
765 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
766 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
767 gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START);
768 gtk_widget_show (label);
769
770 priv->tmpdir = label;
771
772 image = gtk_image_new_from_icon_name ("folder", GTK_ICON_SIZE_BUTTON);
773 gtk_widget_show (image);
774
775 box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
776 gtk_widget_show (box);
777 gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
778 gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
779
780 button = gtk_button_new ();
781 gtk_widget_show (button);
782 gtk_container_add (GTK_CONTAINER (button), box);
783 gtk_widget_set_tooltip_text (button, _("Set the directory where to store temporary files"));
784
785 box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
786 gtk_widget_show (box);
787
788 string = g_strdup_printf ("<b>%s</b>", _("Temporary files"));
789 gtk_box_pack_start (GTK_BOX (vbox),
790 brasero_utils_pack_properties (string,
791 box,
792 button,
793 NULL),
794 FALSE,
795 FALSE, 0);
796 g_free (string);
797 gtk_widget_show (vbox);
798
799 g_signal_connect (button,
800 "clicked",
801 G_CALLBACK (brasero_drive_properties_tmpdir_clicked),
802 object);
803 g_signal_connect (priv->speed,
804 "changed",
805 G_CALLBACK (brasero_drive_properties_rate_changed_cb),
806 object);
807 }
808
809 static void
brasero_drive_properties_finalize(GObject * object)810 brasero_drive_properties_finalize (GObject *object)
811 {
812 BraseroDrivePropertiesPrivate *priv;
813
814 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (object);
815 if (priv->valid_sig) {
816 g_signal_handler_disconnect (priv->session, priv->valid_sig);
817 priv->valid_sig = 0;
818 }
819 if (priv->output_sig) {
820 g_signal_handler_disconnect (priv->session, priv->output_sig);
821 priv->output_sig = 0;
822 }
823 if (priv->session) {
824 g_object_unref (priv->session);
825 priv->session = NULL;
826 }
827
828 G_OBJECT_CLASS (brasero_drive_properties_parent_class)->finalize (object);
829 }
830
831 static void
brasero_drive_properties_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)832 brasero_drive_properties_set_property (GObject *object,
833 guint property_id,
834 const GValue *value,
835 GParamSpec *pspec)
836 {
837 BraseroDrivePropertiesPrivate *priv;
838 BraseroBurnSession *session;
839
840 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (object);
841
842 switch (property_id) {
843 case PROP_SESSION: /* Readable and only writable at creation time */
844 /* NOTE: no need to unref a potential previous session since
845 * it's only set at construct time */
846 session = g_value_get_object (value);
847 priv->session = g_object_ref (session);
848
849 brasero_drive_properties_update (BRASERO_DRIVE_PROPERTIES (object));
850 priv->valid_sig = g_signal_connect (session,
851 "is-valid",
852 G_CALLBACK (brasero_drive_properties_is_valid_cb),
853 object);
854 priv->output_sig = g_signal_connect (session,
855 "output-changed",
856 G_CALLBACK (brasero_drive_properties_output_changed_cb),
857 object);
858 break;
859
860 default:
861 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
862 }
863 }
864
865 static void
brasero_drive_properties_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)866 brasero_drive_properties_get_property (GObject *object,
867 guint property_id,
868 GValue *value,
869 GParamSpec *pspec)
870 {
871 BraseroDrivePropertiesPrivate *priv;
872
873 priv = BRASERO_DRIVE_PROPERTIES_PRIVATE (object);
874
875 switch (property_id) {
876 case PROP_SESSION:
877 g_object_ref (priv->session);
878 g_value_set_object (value, priv->session);
879 break;
880
881 default:
882 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
883 }
884 }
885
886 static void
brasero_drive_properties_class_init(BraseroDrivePropertiesClass * klass)887 brasero_drive_properties_class_init (BraseroDrivePropertiesClass *klass)
888 {
889 GObjectClass *object_class = G_OBJECT_CLASS (klass);
890
891 g_type_class_add_private (klass, sizeof (BraseroDrivePropertiesPrivate));
892
893 object_class->finalize = brasero_drive_properties_finalize;
894 object_class->set_property = brasero_drive_properties_set_property;
895 object_class->get_property = brasero_drive_properties_get_property;
896
897 g_object_class_install_property (object_class,
898 PROP_SESSION,
899 g_param_spec_object ("session",
900 "The session",
901 "The session to work with",
902 BRASERO_TYPE_BURN_SESSION,
903 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
904 }
905
906 GtkWidget *
brasero_drive_properties_new(BraseroSessionCfg * session)907 brasero_drive_properties_new (BraseroSessionCfg *session)
908 {
909 return g_object_new (BRASERO_TYPE_DRIVE_PROPERTIES,
910 "session", session,
911 NULL);
912 }
913