1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3 * brasero
4 * Copyright (C) Philippe Rouquier 2007-2008 <bonfire-app@wanadoo.fr>
5 *
6 * Brasero 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 * brasero is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with brasero. If not, write to:
18 * The Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include <glib.h>
28 #include <glib/gi18n-lib.h>
29
30 #include <gtk/gtk.h>
31
32 #include "brasero-misc.h"
33 #include "brasero-metadata.h"
34
35 #include "brasero-units.h"
36
37 #include "brasero-track.h"
38 #include "brasero-track-stream.h"
39
40 #include "brasero-split-dialog.h"
41 #include "brasero-song-control.h"
42 #include "brasero-utils.h"
43
44 enum {
45 START_COL,
46 END_COL,
47 LENGTH_COL,
48 START_STR_COL,
49 END_STR_COL,
50 LENGTH_STR_COL,
51 COLUMN_NUM,
52 };
53
54 typedef struct _BraseroSplitDialogPrivate BraseroSplitDialogPrivate;
55 struct _BraseroSplitDialogPrivate
56 {
57 GtkWidget *cut;
58
59 GtkListStore *model;
60
61 GtkWidget *tree;
62 GtkWidget *player;
63
64 GtkWidget *notebook;
65 GtkWidget *combo;
66
67 GtkWidget *spin_parts;
68 GtkWidget *spin_sec;
69
70 GtkWidget *silence_label;
71
72 GtkWidget *reset_button;
73 GtkWidget *merge_button;
74 GtkWidget *remove_button;
75
76 gint64 start;
77 gint64 end;
78
79 BraseroMetadata *metadata;
80 };
81
82 #define BRASERO_SPLIT_DIALOG_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_SPLIT_DIALOG, BraseroSplitDialogPrivate))
83
84 G_DEFINE_TYPE (BraseroSplitDialog, brasero_split_dialog, GTK_TYPE_DIALOG);
85
86 void
brasero_split_dialog_set_uri(BraseroSplitDialog * self,const gchar * uri,const gchar * title,const gchar * artist)87 brasero_split_dialog_set_uri (BraseroSplitDialog *self,
88 const gchar *uri,
89 const gchar *title,
90 const gchar *artist)
91 {
92 BraseroSplitDialogPrivate *priv;
93
94 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
95 brasero_song_control_set_uri (BRASERO_SONG_CONTROL (priv->player), uri);
96 brasero_song_control_set_info (BRASERO_SONG_CONTROL (priv->player), title, artist);
97 }
98
99 void
brasero_split_dialog_set_boundaries(BraseroSplitDialog * self,gint64 start,gint64 end)100 brasero_split_dialog_set_boundaries (BraseroSplitDialog *self,
101 gint64 start,
102 gint64 end)
103 {
104 BraseroSplitDialogPrivate *priv;
105 guint64 length;
106
107 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
108
109 if (BRASERO_DURATION_TO_BYTES (start) % 2352)
110 start += BRASERO_BYTES_TO_DURATION (2352 - (BRASERO_DURATION_TO_BYTES (start) % 2352));
111
112 if (BRASERO_DURATION_TO_BYTES (end) % 2352)
113 end += BRASERO_BYTES_TO_DURATION (2352 - (BRASERO_DURATION_TO_BYTES (end) % 2352));
114
115 if (end - start < BRASERO_MIN_STREAM_LENGTH)
116 return;
117
118 priv->start = start;
119 priv->end = end;
120
121 brasero_song_control_set_boundaries (BRASERO_SONG_CONTROL (priv->player),
122 priv->start,
123 priv->end);
124
125 /* Don't allow splitting the track in sections longer than the track
126 * length in seconds */
127 length = (gdouble) brasero_song_control_get_length (BRASERO_SONG_CONTROL (priv->player)) / 1000000000;
128 gtk_spin_button_set_range (GTK_SPIN_BUTTON (priv->spin_sec), 1.0, length);
129 }
130
131 GSList *
brasero_split_dialog_get_slices(BraseroSplitDialog * self)132 brasero_split_dialog_get_slices (BraseroSplitDialog *self)
133 {
134 BraseroSplitDialogPrivate *priv;
135 GSList *retval = NULL;
136 GtkTreeModel *model;
137 GtkTreeIter iter;
138
139 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
140
141 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree));
142 if (!gtk_tree_model_get_iter_first (model, &iter))
143 return NULL;
144
145 do {
146 BraseroAudioSlice *slice;
147
148 slice = g_new0 (BraseroAudioSlice, 1);
149 retval = g_slist_append (retval, slice);
150
151 gtk_tree_model_get (model, &iter,
152 START_COL, &slice->start,
153 END_COL, &slice->end,
154 -1);
155
156 } while (gtk_tree_model_iter_next (model, &iter));
157
158 return retval;
159 }
160
161 static gboolean
brasero_split_dialog_size_error(BraseroSplitDialog * self)162 brasero_split_dialog_size_error (BraseroSplitDialog *self)
163 {
164 GtkWidget *message;
165 GtkResponseType answer;
166
167 message = gtk_message_dialog_new (GTK_WINDOW (self),
168 GTK_DIALOG_DESTROY_WITH_PARENT|
169 GTK_DIALOG_MODAL,
170 GTK_MESSAGE_QUESTION,
171 GTK_BUTTONS_NONE,
172 _("Do you really want to split the track?"));
173
174 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message),
175 _("If you split the track, the size of the new track will be shorter than 6 seconds and will be padded."));
176
177 gtk_dialog_add_button (GTK_DIALOG (message),
178 GTK_STOCK_CANCEL,
179 GTK_RESPONSE_CANCEL);
180 gtk_dialog_add_button (GTK_DIALOG (message),
181 _("_Split"),
182 GTK_RESPONSE_YES);
183
184 answer = gtk_dialog_run (GTK_DIALOG (message));
185 gtk_widget_destroy (message);
186
187 if (answer == GTK_RESPONSE_YES)
188 return TRUE;
189
190 return FALSE;
191 }
192
193 static gboolean
brasero_split_dialog_cut(BraseroSplitDialog * self,gint64 pos,gboolean warn)194 brasero_split_dialog_cut (BraseroSplitDialog *self,
195 gint64 pos,
196 gboolean warn)
197 {
198 BraseroSplitDialogPrivate *priv;
199 BraseroAudioSlice slice = {0,0};
200 GtkTreeModel *model;
201 GtkTreeIter child;
202 GtkTreeIter iter;
203 gchar *length_str;
204 gchar *start_str;
205 gchar *end_str;
206
207 if (!pos)
208 return FALSE;
209
210 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
211
212 /* since pos is in nanosecond we have a small lattitude. Make sure that
213 * is up to the size of a sector */
214 if (BRASERO_DURATION_TO_BYTES (pos) % 2352)
215 pos += BRASERO_BYTES_TO_DURATION (2352 - (BRASERO_DURATION_TO_BYTES (pos) % 2352));
216
217 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree));
218 if (!gtk_tree_model_get_iter_first (model, &iter)) {
219 gint64 end;
220
221 /* nothing in the tree yet */
222 if (priv->end <= 0)
223 end = brasero_song_control_get_length (BRASERO_SONG_CONTROL (priv->player));
224 else
225 end = priv->end;
226
227 /* check that pos > 300 sectors ( == 4 sec ) */
228 if (warn
229 && pos - priv->start < BRASERO_MIN_STREAM_LENGTH
230 && !brasero_split_dialog_size_error (self))
231 return FALSE;
232
233 if (warn
234 && end - (pos + 1) < BRASERO_MIN_STREAM_LENGTH
235 && !brasero_split_dialog_size_error (self))
236 return FALSE;
237
238 length_str = brasero_units_get_time_string (pos - priv->start, TRUE, FALSE);
239 start_str = brasero_units_get_time_string (priv->start, TRUE, FALSE);
240 end_str = brasero_units_get_time_string (pos, TRUE, FALSE);
241
242 gtk_list_store_append (priv->model, &iter);
243 gtk_list_store_set (priv->model, &iter,
244 START_COL, (gint64) priv->start,
245 END_COL, (gint64) pos,
246 LENGTH_COL, (gint64) pos - priv->start,
247 START_STR_COL, start_str,
248 END_STR_COL, end_str,
249 LENGTH_STR_COL, length_str,
250 -1);
251 g_free (length_str);
252 g_free (start_str);
253 g_free (end_str);
254
255 pos ++;
256 length_str = brasero_units_get_time_string (end - pos, TRUE, FALSE);
257 start_str = brasero_units_get_time_string (pos, TRUE, FALSE);
258 end_str = brasero_units_get_time_string (end, TRUE, FALSE);
259
260 gtk_list_store_append (priv->model, &iter);
261 gtk_list_store_set (priv->model, &iter,
262 START_COL, pos,
263 END_COL, end,
264 LENGTH_COL, (gint64) (end - pos),
265 START_STR_COL, start_str,
266 END_STR_COL, end_str,
267 LENGTH_STR_COL, length_str,
268 -1);
269 g_free (length_str);
270 g_free (start_str);
271 g_free (end_str);
272 return TRUE;
273 }
274
275 /* Try to find an already created slice encompassing the position */
276 do {
277 gint64 start;
278 gint64 end;
279
280 gtk_tree_model_get (model, &iter,
281 START_COL, &start,
282 END_COL, &end,
283 -1);
284
285 /* NOTE: if pos == start or pos == end then nothing changes */
286 if (pos <= start || pos >= end)
287 continue;
288
289 /* check the size of the new tracks */
290 if (warn
291 && (pos - start) < BRASERO_MIN_STREAM_LENGTH
292 && !brasero_split_dialog_size_error (self))
293 return FALSE;
294
295 if (warn
296 && (end - (pos + 1)) < BRASERO_MIN_STREAM_LENGTH
297 && !brasero_split_dialog_size_error (self))
298 return FALSE;
299
300 /* Found one */
301 slice.start = start;
302 slice.end = end;
303 break;
304
305 } while (gtk_tree_model_iter_next (model, &iter));
306
307 /* see if we found a slice, if not create a new one starting at pos
308 * until the end of the song */
309
310 if (slice.start == 0 && slice.end == 0) {
311 slice.start = pos;
312
313 /* check if we need to stop this slice at the end of the song
314 * or at the start of the next slice. */
315 if (gtk_tree_model_get_iter_first (model, &iter)) {
316 do {
317 gint64 start;
318 gint64 end;
319
320 gtk_tree_model_get (model, &iter,
321 START_COL, &start,
322 END_COL, &end,
323 -1);
324
325 if (pos >= start)
326 continue;
327
328 /* Found one */
329 slice.end = start - 1;
330 } while (gtk_tree_model_iter_next (model, &iter));
331 }
332
333 if (!slice.end)
334 slice.end = priv->end;
335
336 /* check the size of the new slice */
337 if (warn
338 && (slice.end - slice.start) < BRASERO_MIN_STREAM_LENGTH
339 && !brasero_split_dialog_size_error (self))
340 return FALSE;
341 }
342 else {
343 /* we are in the middle of an existing slice */
344 length_str = brasero_units_get_time_string (pos - slice.start, TRUE, FALSE);
345 end_str = brasero_units_get_time_string (pos, TRUE, FALSE);
346
347 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (model),
348 &child,
349 &iter);
350
351 gtk_list_store_set (priv->model, &child,
352 END_COL, (gint64) pos,
353 LENGTH_COL, (gint64) (pos - slice.start),
354 END_STR_COL, end_str,
355 LENGTH_STR_COL, length_str,
356 -1);
357 g_free (length_str);
358 g_free (end_str);
359
360 /* move the position by one */
361 pos ++;
362 }
363
364 /* create a new one */
365 gtk_list_store_append (priv->model, &child);
366
367 length_str = brasero_units_get_time_string (slice.end - pos, TRUE, FALSE);
368 start_str = brasero_units_get_time_string (pos, TRUE, FALSE);
369 end_str = brasero_units_get_time_string (slice.end, TRUE, FALSE);
370
371 gtk_list_store_set (priv->model, &child,
372 START_COL, pos,
373 END_COL, slice.end,
374 LENGTH_COL, (gint64) (slice.end - pos),
375 START_STR_COL, start_str,
376 END_STR_COL, end_str,
377 LENGTH_STR_COL, length_str,
378 -1);
379
380 g_free (length_str);
381 g_free (start_str);
382 g_free (end_str);
383
384 return TRUE;
385 }
386
387 static void
brasero_split_dialog_remove_range(BraseroSplitDialog * self,gint64 start,gint64 end,gint64 length)388 brasero_split_dialog_remove_range (BraseroSplitDialog *self,
389 gint64 start,
390 gint64 end,
391 gint64 length)
392 {
393 BraseroSplitDialogPrivate *priv;
394 GtkTreeModel *model;
395 GtkTreeIter iter;
396 gchar *length_str;
397 gchar *start_str;
398 gchar *end_str;
399
400 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
401
402 /* align on 2352 byte boundary */
403 if (BRASERO_DURATION_TO_BYTES (start) % 2352)
404 start += BRASERO_BYTES_TO_DURATION (2352 - (BRASERO_DURATION_TO_BYTES (start) % 2352));
405
406 if (BRASERO_DURATION_TO_BYTES (end) % 2352) {
407 end += BRASERO_BYTES_TO_DURATION (2352 - (BRASERO_DURATION_TO_BYTES (end) % 2352));
408 if (end > length)
409 end = length;
410 }
411
412 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree));
413 if (!gtk_tree_model_get_iter_first (model, &iter)) {
414 /* nothing in the tree yet; so create two new segments:
415 * - 0 => start
416 * - end => song end
417 * also make sure that the track is longer than 4 sec */
418 if (start - priv->start < BRASERO_MIN_STREAM_LENGTH
419 && !brasero_split_dialog_size_error (self)) {
420 /* that's not necessarily a good solution */
421 start = BRASERO_MIN_STREAM_LENGTH;
422 if (start > end)
423 end = start;
424 }
425
426 if ((length - end) < BRASERO_MIN_STREAM_LENGTH
427 && !brasero_split_dialog_size_error (self))
428 end = length - BRASERO_MIN_STREAM_LENGTH;
429
430 length_str = brasero_units_get_time_string (start - priv->start, TRUE, FALSE);
431 start_str = brasero_units_get_time_string (priv->start, TRUE, FALSE);
432 end_str = brasero_units_get_time_string (start, TRUE, FALSE);
433
434 gtk_list_store_append (priv->model, &iter);
435 gtk_list_store_set (priv->model, &iter,
436 START_COL, (gint64) priv->start,
437 END_COL, (gint64) start,
438 LENGTH_COL, (gint64) start - priv->start,
439 START_STR_COL, start_str,
440 END_STR_COL, end_str,
441 LENGTH_STR_COL, length_str,
442 -1);
443 g_free (length_str);
444 g_free (start_str);
445 g_free (end_str);
446
447 if (end == length)
448 return;
449
450 length_str = brasero_units_get_time_string (length - end, TRUE, FALSE);
451 start_str = brasero_units_get_time_string (end, TRUE, FALSE);
452 end_str = brasero_units_get_time_string (length, TRUE, FALSE);
453
454 gtk_list_store_append (priv->model, &iter);
455 gtk_list_store_set (priv->model, &iter,
456 START_COL, end,
457 END_COL, length,
458 LENGTH_COL, (gint64) (length - end),
459 START_STR_COL, start_str,
460 END_STR_COL, end_str,
461 LENGTH_STR_COL, length_str,
462 -1);
463 g_free (length_str);
464 g_free (start_str);
465 g_free (end_str);
466 return;
467 }
468
469 do {
470 GtkTreeIter child;
471 gint64 track_start;
472 gint64 track_end;
473
474 gtk_tree_model_get (model, &iter,
475 START_COL, &track_start,
476 END_COL, &track_end,
477 -1);
478
479 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (model),
480 &child,
481 &iter);
482
483 if (start == track_start) {
484 if (start == end)
485 return;
486
487 if (end == track_end) {
488 /* suppress it */
489 gtk_list_store_remove (priv->model, &child);
490 return;
491 }
492
493 if (end < track_end) {
494 /* reduce the size but make sure the remaining
495 * track is > 4 sec */
496 if ((track_end - end) < BRASERO_MIN_STREAM_LENGTH
497 && !brasero_split_dialog_size_error (self))
498 end = track_end - BRASERO_MIN_STREAM_LENGTH;
499
500 start_str = brasero_units_get_time_string (end, TRUE, FALSE);
501 length_str = brasero_units_get_time_string (track_end - end, TRUE, FALSE);
502 gtk_list_store_set (priv->model, &child,
503 START_COL, end,
504 START_STR_COL, start_str,
505 LENGTH_COL, track_end - end,
506 LENGTH_STR_COL, length_str,
507 -1);
508 g_free (length_str);
509 g_free (start_str);
510 }
511 else if (!gtk_list_store_remove (priv->model, &child))
512 return;
513 }
514 else if (start > track_start) {
515 if (start > track_end)
516 continue;
517
518 /* reduce the size but make sure the remaining track is
519 * > 4 sec else change it */
520 if ((start - track_start) < BRASERO_MIN_STREAM_LENGTH
521 && !brasero_split_dialog_size_error (self))
522 start = track_start + BRASERO_MIN_STREAM_LENGTH;
523
524 start_str = brasero_units_get_time_string (start, TRUE, FALSE);
525 length_str = brasero_units_get_time_string (start - track_start, TRUE, FALSE);
526 gtk_list_store_set (priv->model, &child,
527 END_COL, start,
528 END_STR_COL, start_str,
529 LENGTH_COL, start - track_start,
530 LENGTH_STR_COL, length_str,
531 -1);
532 g_free (length_str);
533 g_free (start_str);
534
535 if (end == length)
536 return;
537
538 if (end == track_end)
539 return;
540
541 if (end > track_end)
542 continue;
543
544 /* create a new track with the remaining time.
545 * make sure the remaining track is > 4 sec */
546 if ((track_end - end) < BRASERO_MIN_STREAM_LENGTH
547 && !brasero_split_dialog_size_error (self))
548 end = track_end - BRASERO_MIN_STREAM_LENGTH;
549
550 gtk_list_store_append (priv->model, &child);
551
552 length_str = brasero_units_get_time_string (track_end - end, TRUE, FALSE);
553 start_str = brasero_units_get_time_string (end, TRUE, FALSE);
554 end_str = brasero_units_get_time_string (track_end, TRUE, FALSE);
555
556 gtk_list_store_set (priv->model, &child,
557 START_COL, end,
558 END_COL, track_end,
559 LENGTH_COL, (gint64) (track_end - end),
560 START_STR_COL, start_str,
561 END_STR_COL, end_str,
562 LENGTH_STR_COL, length_str,
563 -1);
564 g_free (length_str);
565 g_free (start_str);
566 g_free (end_str);
567 }
568 else if (end > track_end) {
569 if (!gtk_list_store_remove (priv->model, &child))
570 return;
571 }
572 else if (end == track_end) {
573 gtk_list_store_remove (priv->model, &child);
574 return;
575 }
576 else {
577 if (end == length) {
578 gtk_list_store_remove (priv->model, &child);
579 return;
580 }
581
582 /* resize (make sure about the 4s) */
583 if ((track_end - end) < BRASERO_MIN_STREAM_LENGTH
584 && !brasero_split_dialog_size_error (self))
585 end = track_end - BRASERO_MIN_STREAM_LENGTH;
586
587 start_str = brasero_units_get_time_string (end, TRUE, FALSE);
588 length_str = brasero_units_get_time_string (track_end - end, TRUE, FALSE);
589 gtk_list_store_set (priv->model, &child,
590 START_COL, end,
591 START_STR_COL, start_str,
592 LENGTH_COL, track_end - end,
593 LENGTH_STR_COL, length_str,
594 -1);
595 g_free (length_str);
596 g_free (start_str);
597 }
598
599 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (model),
600 &iter,
601 &child);
602 } while (gtk_tree_model_iter_next (model, &iter));
603 }
604
605 static void
brasero_split_dialog_no_silence_message(BraseroSplitDialog * self)606 brasero_split_dialog_no_silence_message (BraseroSplitDialog *self)
607 {
608 brasero_utils_message_dialog (GTK_WIDGET (self),
609 _("The track wasn't split."),
610 _("No silence could be detected"),
611 GTK_MESSAGE_WARNING);
612 }
613
614 static void
brasero_split_dialog_metadata_finished_cb(BraseroMetadata * metadata,GError * error,BraseroSplitDialog * self)615 brasero_split_dialog_metadata_finished_cb (BraseroMetadata *metadata,
616 GError *error,
617 BraseroSplitDialog *self)
618 {
619 BraseroMetadataInfo info = { NULL, };
620 BraseroSplitDialogPrivate *priv;
621 gboolean added_silence;
622 GSList *iter;
623
624 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
625
626 gtk_widget_set_sensitive (priv->cut, TRUE);
627
628 g_object_unref (priv->metadata);
629 priv->metadata = NULL;
630
631 if (error) {
632 brasero_utils_message_dialog (GTK_WIDGET (self),
633 _("An error occurred while detecting silences."),
634 error->message,
635 GTK_MESSAGE_ERROR);
636 return;
637 }
638
639 brasero_metadata_get_result (metadata, &info, NULL);
640 if (!info.silences) {
641 brasero_split_dialog_no_silence_message (self);
642 return;
643 }
644
645 /* remove silences */
646 added_silence = FALSE;
647 for (iter = info.silences; iter; iter = iter->next) {
648 BraseroMetadataSilence *silence;
649
650 silence = iter->data;
651
652 if (!silence)
653 continue;
654
655 if (silence->start >= priv->end)
656 continue;
657
658 if (silence->end <= priv->start)
659 continue;
660
661 if (silence->start < priv->start)
662 silence->start = priv->start;
663
664 if (silence->end > priv->end)
665 silence->end = priv->end;
666
667 if (!silence->start)
668 brasero_split_dialog_cut (self, silence->end, TRUE);
669 else if (silence->start != silence->end)
670 brasero_split_dialog_remove_range (self,
671 silence->start,
672 silence->end,
673 priv->end - priv->start);
674 else
675 brasero_split_dialog_cut (self, silence->end, TRUE);
676
677 added_silence = TRUE;
678 }
679
680 if (!added_silence)
681 brasero_split_dialog_no_silence_message (self);
682
683 brasero_metadata_info_clear (&info);
684 }
685
686 static gboolean
brasero_split_dialog_clear_confirm_dialog(BraseroSplitDialog * self,const gchar * primary,const gchar * cancel_button,const gchar * ok_button)687 brasero_split_dialog_clear_confirm_dialog (BraseroSplitDialog *self,
688 const gchar *primary,
689 const gchar *cancel_button,
690 const gchar *ok_button)
691 {
692 BraseroSplitDialogPrivate *priv;
693 GtkResponseType answer;
694 GtkTreeModel *model;
695 GtkWidget *message;
696
697 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
698
699 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree));
700 if (!gtk_tree_model_iter_n_children (model, NULL))
701 return TRUE;
702
703 message = gtk_message_dialog_new (GTK_WINDOW (self),
704 GTK_DIALOG_DESTROY_WITH_PARENT|
705 GTK_DIALOG_MODAL,
706 GTK_MESSAGE_QUESTION,
707 GTK_BUTTONS_NONE,
708 "%s",
709 primary);
710
711 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message),
712 _("This will remove all previous results."));
713
714 gtk_dialog_add_button (GTK_DIALOG (message),
715 cancel_button,
716 GTK_RESPONSE_CANCEL);
717 gtk_dialog_add_button (GTK_DIALOG (message),
718 ok_button,
719 GTK_RESPONSE_YES);
720
721 answer = gtk_dialog_run (GTK_DIALOG (message));
722 gtk_widget_destroy (message);
723
724 if (answer != GTK_RESPONSE_YES)
725 return FALSE;
726
727 return TRUE;
728 }
729
730 static void
brasero_split_dialog_cut_clicked_cb(GtkButton * button,BraseroSplitDialog * self)731 brasero_split_dialog_cut_clicked_cb (GtkButton *button,
732 BraseroSplitDialog *self)
733 {
734 BraseroSplitDialogPrivate *priv;
735 guint page;
736
737 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
738
739 page = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->combo));
740 if (page == 0) {
741 gint64 pos;
742
743 /* this one is before since it doesn't wipe all slices */
744 pos = brasero_song_control_get_pos (BRASERO_SONG_CONTROL (priv->player));
745 brasero_split_dialog_cut (self, pos + priv->start, TRUE);
746 return;
747 }
748
749 if (!brasero_split_dialog_clear_confirm_dialog (self,
750 _("Do you really want to carry on with automatic splitting?"),
751 _("_Don't split"),
752 _("_Split")))
753 return;
754
755 if (page == 1) {
756 gint64 sec;
757 gint64 start;
758 gint64 length;
759
760 sec = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->spin_sec));
761
762 sec *= 1000000000;
763 if (sec < BRASERO_MIN_STREAM_LENGTH
764 && !brasero_split_dialog_size_error (self))
765 return;
766
767 length = priv->end - priv->start;
768
769 gtk_list_store_clear (priv->model);
770 for (start = sec; start < length; start += sec)
771 brasero_split_dialog_cut (self, start, FALSE);
772
773 return;
774 }
775
776 if (page == 2) {
777 gint64 step;
778 gint64 start;
779 gint64 parts;
780 gint64 length;
781
782 parts = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->spin_parts));
783
784 length = priv->end - priv->start;
785 step = length / parts;
786
787 if (step < BRASERO_MIN_STREAM_LENGTH
788 && !brasero_split_dialog_size_error (self))
789 return;
790
791 gtk_list_store_clear (priv->model);
792
793 parts --;
794 for (start = step; start < length && parts; start += step, parts --)
795 brasero_split_dialog_cut (self, start, FALSE);
796
797 return;
798 }
799
800 gtk_list_store_clear (priv->model);
801
802 priv->metadata = brasero_metadata_new ();
803 g_signal_connect (priv->metadata,
804 "completed",
805 G_CALLBACK (brasero_split_dialog_metadata_finished_cb),
806 self);
807 brasero_metadata_get_info_async (priv->metadata,
808 brasero_song_control_get_uri (BRASERO_SONG_CONTROL (priv->player)),
809 BRASERO_METADATA_FLAG_SILENCES);
810
811 /* stop anything from playing and grey out things */
812 gtk_widget_set_sensitive (priv->cut, FALSE);
813 }
814
815 static void
brasero_split_dialog_merge_clicked_cb(GtkButton * button,BraseroSplitDialog * self)816 brasero_split_dialog_merge_clicked_cb (GtkButton *button,
817 BraseroSplitDialog *self)
818 {
819 BraseroSplitDialogPrivate *priv;
820 GtkTreeSelection *selection;
821 GtkTreeModel *model;
822 GtkTreeIter iter;
823
824 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
825
826 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree));
827 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree));
828 if (!gtk_tree_model_get_iter_first (model, &iter))
829 return;
830
831 do {
832 guint64 end;
833 guint64 start;
834 gchar *end_str;
835 gchar *start_str;
836 GtkTreeIter next;
837 gchar *length_str;
838 GtkTreeIter child;
839
840 if (!gtk_tree_selection_iter_is_selected (selection, &iter))
841 continue;
842
843 next = iter;
844 if (!gtk_tree_model_iter_next (model, &next))
845 continue;
846
847 if (!gtk_tree_selection_iter_is_selected (selection, &next))
848 continue;
849
850 gtk_tree_model_get (model, &iter,
851 START_COL, &start,
852 -1);
853
854 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (model),
855 &child,
856 &iter);
857
858 do {
859 GtkTreeIter next_child;
860
861 gtk_tree_model_get (model, &next,
862 END_COL, &end,
863 -1);
864
865 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (model),
866 &next_child,
867 &next);
868
869 if (!gtk_list_store_remove (priv->model, &next_child))
870 break;
871
872 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (model),
873 &next,
874 &next_child);
875
876 } while (gtk_tree_selection_iter_is_selected (selection, &next));
877
878 length_str = brasero_units_get_time_string (end - start, TRUE, FALSE);
879 start_str = brasero_units_get_time_string (start, TRUE, FALSE);
880 end_str = brasero_units_get_time_string (end, TRUE, FALSE);
881
882 gtk_list_store_set (priv->model, &child,
883 START_COL, (gint64) start,
884 END_COL, (gint64) end,
885 LENGTH_COL, (gint64) end - start,
886 START_STR_COL, start_str,
887 END_STR_COL, end_str,
888 LENGTH_STR_COL, length_str,
889 -1);
890 g_free (length_str);
891 g_free (start_str);
892 g_free (end_str);
893
894 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (model),
895 &iter,
896 &child);
897
898 } while (gtk_tree_model_iter_next (model, &iter));
899
900 if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (priv->model), NULL) == 1)
901 gtk_list_store_clear (priv->model);
902 }
903
904 static void
brasero_split_dialog_remove_clicked_cb(GtkButton * button,BraseroSplitDialog * self)905 brasero_split_dialog_remove_clicked_cb (GtkButton *button,
906 BraseroSplitDialog *self)
907 {
908 BraseroSplitDialogPrivate *priv;
909 GList *references = NULL;
910 GtkTreeModel *model;
911 GList *selected;
912 GList *iter;
913
914 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
915
916 selected = gtk_tree_selection_get_selected_rows (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree)), &model);
917
918 /* since we are going to modify the tree take references */
919 for (iter = selected; iter; iter = iter->next) {
920 GtkTreePath *treepath;
921 GtkTreeRowReference *reference;
922
923 treepath = iter->data;
924 reference = gtk_tree_row_reference_new (model, treepath);
925 gtk_tree_path_free (treepath);
926
927 references = g_list_prepend (references, reference);
928 }
929 g_list_free (selected);
930
931 for (iter = references; iter; iter = iter->next) {
932 GtkTreeRowReference *reference;
933 GtkTreePath *treepath;
934 GtkTreeIter child;
935 GtkTreeIter row;
936
937 reference = iter->data;
938
939 treepath = gtk_tree_row_reference_get_path (reference);
940 gtk_tree_row_reference_free (reference);
941 if (!treepath)
942 continue;
943
944 if (!gtk_tree_model_get_iter (model, &row, treepath)) {
945 gtk_tree_path_free (treepath);
946 continue;
947 }
948
949 gtk_tree_path_free (treepath);
950
951 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (model),
952 &child,
953 &row);
954
955 gtk_list_store_remove (priv->model, &child);
956 }
957 g_list_free (references);
958 }
959
960 static void
brasero_split_dialog_reset_clicked_cb(GtkButton * button,BraseroSplitDialog * self)961 brasero_split_dialog_reset_clicked_cb (GtkButton *button,
962 BraseroSplitDialog *self)
963 {
964 BraseroSplitDialogPrivate *priv;
965
966 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
967 if (!brasero_split_dialog_clear_confirm_dialog (self,
968 _("Do you really want to empty the slices preview?"),
969 GTK_STOCK_CANCEL,
970 _("Re_move All")))
971 return;
972
973 gtk_list_store_clear (priv->model);
974 }
975
976 static void
brasero_split_dialog_combo_changed_cb(GtkComboBox * combo,BraseroSplitDialog * self)977 brasero_split_dialog_combo_changed_cb (GtkComboBox *combo,
978 BraseroSplitDialog *self)
979 {
980 BraseroSplitDialogPrivate *priv;
981 guint page;
982
983 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
984 page = gtk_combo_box_get_active (combo);
985 gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), page);
986 }
987
988 static void
brasero_split_dialog_selection_changed_cb(GtkTreeSelection * selection,BraseroSplitDialog * self)989 brasero_split_dialog_selection_changed_cb (GtkTreeSelection *selection,
990 BraseroSplitDialog *self)
991 {
992 BraseroSplitDialogPrivate *priv;
993 GList *selected;
994
995 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
996
997 selected = gtk_tree_selection_get_selected_rows (selection, NULL);
998 if (selected) {
999 g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
1000 g_list_free (selected);
1001
1002 gtk_widget_set_sensitive (priv->merge_button, TRUE);
1003 gtk_widget_set_sensitive (priv->remove_button, TRUE);
1004 }
1005 else {
1006 gtk_widget_set_sensitive (priv->merge_button, FALSE);
1007 gtk_widget_set_sensitive (priv->remove_button, FALSE);
1008 }
1009 }
1010
1011 static void
brasero_split_dialog_row_inserted_cb(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,BraseroSplitDialog * self)1012 brasero_split_dialog_row_inserted_cb (GtkTreeModel *model,
1013 GtkTreePath *path,
1014 GtkTreeIter *iter,
1015 BraseroSplitDialog *self)
1016 {
1017 BraseroSplitDialogPrivate *priv;
1018
1019 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
1020 gtk_widget_set_sensitive (priv->reset_button, TRUE);
1021 }
1022
1023 static void
brasero_split_dialog_row_deleted_cb(GtkTreeModel * model,GtkTreePath * path,BraseroSplitDialog * self)1024 brasero_split_dialog_row_deleted_cb (GtkTreeModel *model,
1025 GtkTreePath *path,
1026 BraseroSplitDialog *self)
1027 {
1028 BraseroSplitDialogPrivate *priv;
1029 GtkTreeIter iter;
1030
1031 priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
1032 if (!gtk_tree_model_get_iter_first (model, &iter))
1033 gtk_widget_set_sensitive (priv->reset_button, FALSE);
1034 }
1035
1036 static void
brasero_split_dialog_init(BraseroSplitDialog * object)1037 brasero_split_dialog_init (BraseroSplitDialog *object)
1038 {
1039 gchar *title;
1040 GtkWidget *vbox;
1041 GtkWidget *hbox;
1042 GtkWidget *vbox2;
1043 GtkWidget *hbox2;
1044 GtkWidget *label;
1045 GtkWidget *scroll;
1046 GtkWidget *button;
1047 GtkTreeModel *model;
1048 GtkSizeGroup *size_group;
1049 GtkCellRenderer *renderer;
1050 GtkTreeViewColumn *column;
1051 BraseroSplitDialogPrivate *priv;
1052
1053 priv = BRASERO_SPLIT_DIALOG_PRIVATE (object);
1054
1055 gtk_window_set_title (GTK_WINDOW (object), _("Split Track"));
1056 gtk_window_set_default_size (GTK_WINDOW (object), 500, 600);
1057
1058 gtk_dialog_add_button (GTK_DIALOG (object), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
1059 gtk_dialog_add_button (GTK_DIALOG (object), GTK_STOCK_OK, GTK_RESPONSE_OK);
1060
1061 vbox = gtk_dialog_get_content_area (GTK_DIALOG (object));
1062 gtk_box_set_spacing (GTK_BOX (vbox), 0);
1063
1064 size_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
1065
1066 /* Slicing method */
1067 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
1068 gtk_widget_show (hbox);
1069
1070 priv->combo = gtk_combo_box_text_new ();
1071
1072 label = gtk_label_new_with_mnemonic (_("M_ethod:"));
1073 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1074 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->combo);
1075 gtk_widget_show (label);
1076 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
1077
1078 gtk_widget_set_tooltip_text (priv->combo, _("Method to be used to split the track"));
1079 gtk_widget_show (priv->combo);
1080 gtk_box_pack_start (GTK_BOX (hbox), priv->combo, TRUE, TRUE, 0);
1081 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (priv->combo), _("Split track manually"));
1082 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (priv->combo), _("Split track in parts with a fixed length"));
1083 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (priv->combo), _("Split track in a fixed number of parts"));
1084 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (priv->combo), _("Split track for each silence"));
1085 g_signal_connect (priv->combo,
1086 "changed",
1087 G_CALLBACK (brasero_split_dialog_combo_changed_cb),
1088 object);
1089
1090 button = brasero_utils_make_button (_("_Slice"),
1091 NULL,
1092 "transform-crop-and-resize",
1093 GTK_ICON_SIZE_BUTTON);
1094 gtk_widget_show (button);
1095 gtk_size_group_add_widget (size_group, button);
1096 gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1097 g_signal_connect (button,
1098 "clicked",
1099 G_CALLBACK (brasero_split_dialog_cut_clicked_cb),
1100 object);
1101 gtk_widget_set_tooltip_text (button, _("Add a splitting point"));
1102 priv->cut = button;
1103
1104 priv->notebook = gtk_notebook_new ();
1105 gtk_widget_show (priv->notebook);
1106 gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
1107 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
1108
1109 priv->player = brasero_song_control_new ();
1110 gtk_widget_show (priv->player);
1111 gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->player, NULL);
1112
1113 hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
1114 gtk_widget_show (hbox2);
1115 gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), hbox2, NULL);
1116
1117 /* Translators: this goes with the next (= "seconds") */
1118 label = gtk_label_new (_("Split this track every"));
1119 gtk_widget_show (label);
1120 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1121
1122 priv->spin_sec = gtk_spin_button_new_with_range (1.0, 1000.0, 1.0);
1123 gtk_widget_show (priv->spin_sec);
1124 gtk_box_pack_start (GTK_BOX (hbox2), priv->spin_sec, FALSE, FALSE, 0);
1125
1126 /* Translators: this goes with the previous (= "Split track every") */
1127 label = gtk_label_new (_("seconds"));
1128 gtk_widget_show (label);
1129 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1130
1131 hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
1132 gtk_widget_show (hbox2);
1133 gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), hbox2, NULL);
1134
1135 /* Translators: this goes with the next (= "parts") */
1136 label = gtk_label_new (_("Split this track in"));
1137 gtk_widget_show (label);
1138 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1139
1140 priv->spin_parts = gtk_spin_button_new_with_range (2.0, 1000.0, 1.0);
1141 gtk_widget_show (priv->spin_parts);
1142 gtk_box_pack_start (GTK_BOX (hbox2), priv->spin_parts, FALSE, FALSE, 0);
1143
1144 /* Translators: this goes with the previous (= "Split this track in") */
1145 label = gtk_label_new (_("parts"));
1146 gtk_widget_show (label);
1147 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1148
1149 priv->silence_label = gtk_label_new (NULL);
1150 gtk_widget_show (priv->silence_label);
1151 gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->silence_label, NULL);
1152
1153 title = g_strdup_printf ("<b>%s</b>", _("Slicing Method"));
1154 gtk_box_pack_start (GTK_BOX (vbox),
1155 brasero_utils_pack_properties (title,
1156 priv->notebook,
1157 hbox,
1158 NULL),
1159 FALSE,
1160 FALSE,
1161 0);
1162 g_free (title);
1163
1164 /* slices preview */
1165 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
1166 gtk_widget_show (hbox);
1167
1168 priv->model = gtk_list_store_new (COLUMN_NUM,
1169 G_TYPE_INT64,
1170 G_TYPE_INT64,
1171 G_TYPE_INT64,
1172 G_TYPE_STRING,
1173 G_TYPE_STRING,
1174 G_TYPE_STRING);
1175
1176 g_signal_connect (priv->model,
1177 "row-inserted",
1178 G_CALLBACK (brasero_split_dialog_row_inserted_cb),
1179 object);
1180 g_signal_connect (priv->model,
1181 "row-deleted",
1182 G_CALLBACK (brasero_split_dialog_row_deleted_cb),
1183 object);
1184
1185 model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (priv->model));
1186 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
1187 START_COL,
1188 GTK_SORT_ASCENDING);
1189
1190 scroll = gtk_scrolled_window_new (NULL, NULL);
1191 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
1192 GTK_SHADOW_IN);
1193 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
1194 GTK_POLICY_AUTOMATIC,
1195 GTK_POLICY_AUTOMATIC);
1196 gtk_widget_show (scroll);
1197 gtk_box_pack_start (GTK_BOX (hbox), scroll, TRUE, TRUE, 0);
1198
1199 priv->tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
1200 gtk_tree_view_set_enable_tree_lines (GTK_TREE_VIEW (priv->tree), TRUE);
1201 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (priv->tree), TRUE);
1202 gtk_tree_view_set_rubber_banding (GTK_TREE_VIEW (priv->tree), TRUE);
1203
1204 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree)),
1205 GTK_SELECTION_MULTIPLE);
1206
1207 gtk_widget_show (priv->tree);
1208 gtk_container_add (GTK_CONTAINER (scroll), priv->tree);
1209
1210 renderer = gtk_cell_renderer_text_new ();
1211 column = gtk_tree_view_column_new_with_attributes (_("Start"),
1212 renderer,
1213 "text", START_STR_COL,
1214 NULL);
1215 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree), column);
1216
1217 renderer = gtk_cell_renderer_text_new ();
1218 column = gtk_tree_view_column_new_with_attributes (_("End"),
1219 renderer,
1220 "text", END_STR_COL,
1221 NULL);
1222 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree), column);
1223
1224 renderer = gtk_cell_renderer_text_new ();
1225 column = gtk_tree_view_column_new_with_attributes (_("Length"),
1226 renderer,
1227 "text", LENGTH_STR_COL,
1228 NULL);
1229 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree), column);
1230
1231 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree)),
1232 "changed",
1233 G_CALLBACK (brasero_split_dialog_selection_changed_cb),
1234 object);
1235
1236 /* buttons */
1237 vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
1238 gtk_widget_show (vbox2);
1239 gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, TRUE, 0);
1240
1241 button = brasero_utils_make_button (_("Mer_ge"),
1242 NULL,
1243 NULL,
1244 GTK_ICON_SIZE_BUTTON);
1245 gtk_widget_show (button);
1246 gtk_size_group_add_widget (size_group, button);
1247 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
1248 g_signal_connect (button,
1249 "clicked",
1250 G_CALLBACK (brasero_split_dialog_merge_clicked_cb),
1251 object);
1252 gtk_widget_set_tooltip_text (button, _("Merge a selected slice with the next selected one"));
1253 priv->merge_button = button;
1254
1255 button = brasero_utils_make_button (_("_Remove"),
1256 GTK_STOCK_REMOVE,
1257 NULL,
1258 GTK_ICON_SIZE_BUTTON);
1259 gtk_widget_show (button);
1260 gtk_size_group_add_widget (size_group, button);
1261 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
1262 g_signal_connect (button,
1263 "clicked",
1264 G_CALLBACK (brasero_split_dialog_remove_clicked_cb),
1265 object);
1266 gtk_widget_set_tooltip_text (button, _("Remove the selected slices"));
1267 priv->remove_button = button;
1268
1269 button = brasero_utils_make_button (_("Re_move All"),
1270 NULL,
1271 NULL,
1272 GTK_ICON_SIZE_BUTTON);
1273 gtk_widget_show (button);
1274 gtk_size_group_add_widget (size_group, button);
1275 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
1276 g_signal_connect (button,
1277 "clicked",
1278 G_CALLBACK (brasero_split_dialog_reset_clicked_cb),
1279 object);
1280 gtk_widget_set_tooltip_text (button, _("Clear the slices preview"));
1281 priv->reset_button = button;
1282
1283 gtk_widget_set_sensitive (priv->reset_button, FALSE);
1284 gtk_widget_set_sensitive (priv->merge_button, FALSE);
1285 gtk_widget_set_sensitive (priv->remove_button, FALSE);
1286
1287 vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
1288 gtk_widget_show (vbox2);
1289
1290 label = gtk_label_new_with_mnemonic (_("_List of slices that are to be created:"));
1291 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1292 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->tree);
1293 gtk_widget_show (label);
1294
1295 gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
1296 gtk_box_pack_start (GTK_BOX (vbox2), hbox, TRUE, TRUE, 0);
1297
1298 title = g_strdup_printf ("<b>%s</b>", _("Slices Preview"));
1299 gtk_box_pack_start (GTK_BOX (vbox),
1300 brasero_utils_pack_properties (title,
1301 vbox2,
1302 NULL),
1303 TRUE,
1304 TRUE,
1305 0);
1306 g_free (title);
1307
1308 gtk_combo_box_set_active (GTK_COMBO_BOX (priv->combo), 0);
1309 g_object_unref (size_group);
1310 }
1311
1312 static void
brasero_split_dialog_finalize(GObject * object)1313 brasero_split_dialog_finalize (GObject *object)
1314 {
1315 BraseroSplitDialogPrivate *priv;
1316
1317 priv = BRASERO_SPLIT_DIALOG_PRIVATE (object);
1318 if (priv->metadata) {
1319 brasero_metadata_cancel (priv->metadata);
1320 g_object_unref (priv->metadata);
1321 priv->metadata = NULL;
1322 }
1323
1324 G_OBJECT_CLASS (brasero_split_dialog_parent_class)->finalize (object);
1325 }
1326
1327 static void
brasero_split_dialog_class_init(BraseroSplitDialogClass * klass)1328 brasero_split_dialog_class_init (BraseroSplitDialogClass *klass)
1329 {
1330 GObjectClass* object_class = G_OBJECT_CLASS (klass);
1331
1332 g_type_class_add_private (klass, sizeof (BraseroSplitDialogPrivate));
1333
1334 object_class->finalize = brasero_split_dialog_finalize;
1335 }
1336
1337 GtkWidget *
brasero_split_dialog_new(void)1338 brasero_split_dialog_new (void)
1339 {
1340 return GTK_WIDGET (g_object_new (BRASERO_TYPE_SPLIT_DIALOG, NULL));
1341 }
1342