1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
3 /***************************************************************************
4 * brasero-project-manager.c
5 *
6 * mer mai 24 14:22:56 2006
7 * Copyright 2006 Rouquier Philippe
8 * brasero-app@wanadoo.fr
9 ***************************************************************************/
10
11 /*
12 * Brasero is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * Brasero is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to:
24 * The Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor
26 * Boston, MA 02110-1301, USA.
27 */
28
29 #include <string.h>
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 <gtk/gtk.h>
40
41 #include "brasero-io.h"
42
43 #include "brasero-units.h"
44 #include "brasero-medium-monitor.h"
45
46 #include "brasero-app.h"
47 #include "brasero-utils.h"
48 #include "brasero-project.h"
49 #include "brasero-layout.h"
50 #include "brasero-project-manager.h"
51 #include "brasero-file-chooser.h"
52 #include "brasero-uri-container.h"
53 #include "brasero-project-type-chooser.h"
54
55 #ifdef BUILD_PLAYLIST
56 #include "brasero-playlist.h"
57 #endif
58
59 #ifdef BUILD_PREVIEW
60 #include "brasero-preview.h"
61 #endif
62
63 static void brasero_project_manager_class_init (BraseroProjectManagerClass *klass);
64 static void brasero_project_manager_init (BraseroProjectManager *sp);
65 static void brasero_project_manager_finalize (GObject *object);
66
67 static void
68 brasero_project_manager_type_changed_cb (BraseroProjectTypeChooser *chooser,
69 BraseroProjectType type,
70 BraseroProjectManager *manager);
71
72 static void
73 brasero_project_manager_new_cover_cb (GtkAction *action, BraseroProjectManager *manager);
74 static void
75 brasero_project_manager_new_empty_prj_cb (GtkAction *action, BraseroProjectManager *manager);
76 static void
77 brasero_project_manager_new_audio_prj_cb (GtkAction *action, BraseroProjectManager *manager);
78 static void
79 brasero_project_manager_new_data_prj_cb (GtkAction *action, BraseroProjectManager *manager);
80 static void
81 brasero_project_manager_new_video_prj_cb (GtkAction *action, BraseroProjectManager *manager);
82 static void
83 brasero_project_manager_new_copy_prj_cb (GtkAction *action, BraseroProjectManager *manager);
84 static void
85 brasero_project_manager_new_iso_prj_cb (GtkAction *action, BraseroProjectManager *manager);
86 static void
87 brasero_project_manager_open_cb (GtkAction *action, BraseroProjectManager *manager);
88
89 static void
90 brasero_project_manager_selected_uris_changed (BraseroURIContainer *container,
91 BraseroProjectManager *manager);
92
93 /* menus */
94 static GtkActionEntry entries [] = {
95 {"Cover", NULL, N_("_Cover Editor"), NULL,
96 N_("Design and print covers for CDs"), G_CALLBACK (brasero_project_manager_new_cover_cb)},
97 {"New", GTK_STOCK_NEW, N_("_New Project"), NULL,
98 N_("Create a new project"), NULL },
99 {"NewChoose", GTK_STOCK_NEW, N_("_Empty Project"), NULL,
100 N_("Let you choose your new project"), G_CALLBACK (brasero_project_manager_new_empty_prj_cb)},
101 {"NewAudio", "media-optical-audio-new", N_("New _Audio Project"), NULL,
102 N_("Create a traditional audio CD that will be playable on computers and stereos"), G_CALLBACK (brasero_project_manager_new_audio_prj_cb)},
103 {"NewData", "media-optical-data-new", N_("New _Data Project"), NULL,
104 N_("Create a CD/DVD containing any type of data that can only be read on a computer"), G_CALLBACK (brasero_project_manager_new_data_prj_cb)},
105 {"NewVideo", "media-optical-video-new", N_("New _Video Project"), NULL,
106 N_("Create a video DVD or an SVCD that is readable on TV readers"), G_CALLBACK (brasero_project_manager_new_video_prj_cb)},
107 {"NewCopy", "media-optical-copy", N_("Copy _Disc…"), NULL,
108 N_("Create a 1:1 copy of an audio CD or a data CD/DVD on your hard disk or on another CD/DVD"), G_CALLBACK (brasero_project_manager_new_copy_prj_cb)},
109 {"NewIso", "iso-image-burn", N_("_Burn Image…"), NULL,
110 N_("Burn an existing CD/DVD image to disc"), G_CALLBACK (brasero_project_manager_new_iso_prj_cb)},
111
112 {"Open", GTK_STOCK_OPEN, N_("_Open…"), NULL,
113 N_("Open a project"), G_CALLBACK (brasero_project_manager_open_cb)},
114 };
115
116 static const char *description = {
117 "<ui>"
118 "<menubar name='menubar' >"
119 "<menu action='ProjectMenu'>"
120 "<placeholder name='ProjectPlaceholder'>"
121 "<menu action='New'>"
122 "<menuitem action='NewAudio'/>"
123 "<menuitem action='NewData'/>"
124 "<menuitem action='NewVideo'/>"
125 "<menuitem action='NewCopy'/>"
126 "<menuitem action='NewIso'/>"
127 "</menu>"
128 "</placeholder>"
129
130 "<placeholder name='ProjectPlaceholder'>"
131 "<separator/>"
132 "<menuitem action='Open'/>"
133 "<menuitem action='RecentProjects'/>"
134 "<separator/>"
135 "</placeholder>"
136
137 "</menu>"
138
139 "<menu action='ToolMenu'>"
140
141 "<placeholder name='DiscPlaceholder'>"
142 "<separator/>"
143 "<menuitem action='Cover'/>"
144 "<separator/>"
145 "</placeholder>"
146
147 "</menu>"
148 "</menubar>"
149 "</ui>"
150 };
151
152 struct BraseroProjectManagerPrivate {
153 BraseroProjectType type;
154 BraseroIOJobBase *size_preview;
155
156 GtkWidget *project;
157 GtkWidget *layout;
158
159 gchar **selected;
160 guint preview_id;
161
162 guint status_ctx;
163
164 GtkActionGroup *action_group;
165 };
166
167 #define BRASERO_PROJECT_MANAGER_CONNECT_CHANGED(manager, container) \
168 g_signal_connect (container, \
169 "uri-selected", \
170 G_CALLBACK (brasero_project_manager_selected_uris_changed), \
171 manager);
172
173 static GObjectClass *parent_class = NULL;
174
175 GType
brasero_project_manager_get_type()176 brasero_project_manager_get_type ()
177 {
178 static GType type = 0;
179
180 if(type == 0) {
181 static const GTypeInfo our_info = {
182 sizeof (BraseroProjectManagerClass),
183 NULL,
184 NULL,
185 (GClassInitFunc)brasero_project_manager_class_init,
186 NULL,
187 NULL,
188 sizeof (BraseroProjectManager),
189 0,
190 (GInstanceInitFunc)brasero_project_manager_init,
191 };
192
193 type = g_type_register_static (GTK_TYPE_NOTEBOOK,
194 "BraseroProjectManager",
195 &our_info,
196 0);
197 }
198
199 return type;
200 }
201
202 static void
brasero_project_manager_new_cover_cb(GtkAction * action,BraseroProjectManager * manager)203 brasero_project_manager_new_cover_cb (GtkAction *action,
204 BraseroProjectManager *manager)
205 {
206 BraseroJacketEdit *edit;
207 GtkWidget *toplevel;
208 GtkWidget *dialog;
209
210 if (manager->priv->type == BRASERO_PROJECT_TYPE_AUDIO) {
211 brasero_project_create_audio_cover (BRASERO_PROJECT (manager->priv->project));
212 return;
213 }
214
215 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (manager));
216 dialog = brasero_jacket_edit_dialog_new (toplevel, &edit);
217
218 /* This strange hack is a way to workaround #568358.
219 * At one point we'll need to hide the dialog which means it
220 * will anwer with a GTK_RESPONSE_NONE */
221 while (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_NONE)
222 gtk_widget_show (GTK_WIDGET (dialog));
223
224 gtk_widget_destroy (dialog);
225 }
226
227 static void
brasero_project_manager_set_statusbar(BraseroProjectManager * manager,guint64 files_size,gint invalid_num,gint files_num)228 brasero_project_manager_set_statusbar (BraseroProjectManager *manager,
229 guint64 files_size,
230 gint invalid_num,
231 gint files_num)
232 {
233 gchar *status_string = NULL;
234 GtkWidget *status;
235 gint valid_num;
236
237 status = brasero_app_get_statusbar1 (brasero_app_get_default ());
238
239 if (!manager->priv->status_ctx)
240 manager->priv->status_ctx = gtk_statusbar_get_context_id (GTK_STATUSBAR (status),
241 "size_info");
242
243 gtk_statusbar_pop (GTK_STATUSBAR (status), manager->priv->status_ctx);
244
245 valid_num = files_num - invalid_num;
246 if (!invalid_num && valid_num) {
247 gchar *size_string;
248
249 if (manager->priv->type == BRASERO_PROJECT_TYPE_AUDIO
250 || manager->priv->type == BRASERO_PROJECT_TYPE_VIDEO)
251 size_string = brasero_units_get_time_string (files_size, TRUE, FALSE);
252 else if (manager->priv->type == BRASERO_PROJECT_TYPE_DATA)
253 size_string = g_format_size (files_size);
254 else
255 return;
256
257 /* Translators: the %s is a string representing the total size
258 * of the file selection */
259 status_string = g_strdup_printf (ngettext ("%d file selected (%s)", "%d files selected (%s)", files_num),
260 files_num,
261 size_string);
262 g_free (size_string);
263 }
264 else if (valid_num) {
265 gchar *size_string = NULL;
266
267 if (manager->priv->type == BRASERO_PROJECT_TYPE_AUDIO
268 || manager->priv->type == BRASERO_PROJECT_TYPE_VIDEO) {
269 size_string = brasero_units_get_time_string (files_size, TRUE, FALSE);
270 status_string = g_strdup_printf (ngettext ("%d file is supported (%s)", "%d files are supported (%s)", valid_num),
271 valid_num,
272 size_string);
273 }
274 else if (manager->priv->type == BRASERO_PROJECT_TYPE_DATA) {
275 size_string = g_format_size (files_size);
276 status_string = g_strdup_printf (ngettext ("%d file can be added (%s)", "%d selected files can be added (%s)", valid_num),
277 valid_num,
278 size_string);
279 }
280 else
281 return;
282
283 g_free (size_string);
284 }
285 else if (invalid_num) {
286 if (manager->priv->type == BRASERO_PROJECT_TYPE_DATA)
287 status_string = g_strdup_printf (ngettext ("No file can be added (%i selected file)",
288 "No file can be added (%i selected files)",
289 files_num),
290 files_num);
291 else if (manager->priv->type == BRASERO_PROJECT_TYPE_AUDIO
292 || manager->priv->type == BRASERO_PROJECT_TYPE_VIDEO)
293 status_string = g_strdup_printf (ngettext ("No file is supported (%i selected file)",
294 "No file is supported (%i selected files)",
295 files_num),
296 files_num);
297 }
298 else
299 status_string = g_strdup (_("No file selected"));
300
301 gtk_statusbar_push (GTK_STATUSBAR (status), manager->priv->status_ctx,
302 status_string);
303 g_free (status_string);
304 }
305
306 static void
brasero_project_manager_size_preview(GObject * object,GError * error,const gchar * uri,GFileInfo * info,gpointer user_data)307 brasero_project_manager_size_preview (GObject *object,
308 GError *error,
309 const gchar *uri,
310 GFileInfo *info,
311 gpointer user_data)
312 {
313 BraseroProjectManager *manager = BRASERO_PROJECT_MANAGER (object);
314 guint64 files_size;
315 gint invalid_num;
316 gint files_num;
317
318 invalid_num = g_file_info_get_attribute_uint32 (info, BRASERO_IO_COUNT_INVALID);
319 files_size = g_file_info_get_attribute_uint64 (info, BRASERO_IO_COUNT_SIZE);
320 files_num = g_file_info_get_attribute_uint32 (info, BRASERO_IO_COUNT_NUM);
321 brasero_project_manager_set_statusbar (manager,
322 files_size,
323 invalid_num,
324 files_num);
325 }
326 /*
327 static void
328 brasero_project_manager_size_preview_progress (GObject *object,
329 BraseroIOJobProgress *progress,
330 gpointer user_data)
331 {
332 BraseroProjectManager *manager = BRASERO_PROJECT_MANAGER (object);
333 guint64 files_size;
334 gint files_num;
335
336 files_size = brasero_io_job_progress_get_total (progress);
337 files_num = brasero_io_job_progress_get_file_processed (progress);
338 brasero_project_manager_set_statusbar (manager,
339 files_size,
340 0,
341 files_num);
342 }
343 */
344 static gboolean
brasero_project_manager_selected_uris_preview(gpointer data)345 brasero_project_manager_selected_uris_preview (gpointer data)
346 {
347 BraseroProjectManager *manager = BRASERO_PROJECT_MANAGER (data);
348 BraseroIOFlags flags;
349 GSList *list = NULL;
350 gchar **iter;
351
352 if (!manager->priv->size_preview)
353 manager->priv->size_preview = brasero_io_register (G_OBJECT (manager),
354 brasero_project_manager_size_preview,
355 NULL,
356 NULL);
357
358 for (iter = manager->priv->selected; iter && *iter; iter ++)
359 list = g_slist_prepend (list, *iter);
360
361 flags = BRASERO_IO_INFO_IDLE;
362 if (manager->priv->type == BRASERO_PROJECT_TYPE_AUDIO
363 || manager->priv->type == BRASERO_PROJECT_TYPE_VIDEO)
364 flags |= BRASERO_IO_INFO_METADATA;
365 else if (manager->priv->type == BRASERO_PROJECT_TYPE_DATA)
366 flags |= BRASERO_IO_INFO_RECURSIVE;
367
368 brasero_io_get_file_count (list,
369 manager->priv->size_preview,
370 flags,
371 NULL);
372
373 g_slist_free (list);
374 manager->priv->preview_id = 0;
375 return FALSE;
376 }
377
378 void
brasero_project_manager_selected_uris_changed(BraseroURIContainer * container,BraseroProjectManager * manager)379 brasero_project_manager_selected_uris_changed (BraseroURIContainer *container,
380 BraseroProjectManager *manager)
381 {
382 gchar **uris;
383
384 /* Before cancelling everything, check that the size really changed
385 * like in the case of double clicking or if the user selected one
386 * file and double clicked on it afterwards.
387 * NOTE: the following expects each URI to be unique. */
388 uris = brasero_uri_container_get_selected_uris (container);
389 if (uris) {
390 gchar **iter;
391 guint num = 0;
392 gboolean found = FALSE;
393
394 for (iter = manager->priv->selected; iter && *iter; iter ++) {
395 gchar **uri;
396
397 found = FALSE;
398 for (uri = uris; uri && *uri; uri ++) {
399 if (!strcmp (*uri, *iter)) {
400 found = TRUE;
401 break;
402 }
403 }
404
405 if (!found)
406 break;
407
408 num ++;
409 }
410
411 if (found) {
412 guint num_new = 0;
413
414 for (iter = uris; iter && *iter; iter ++)
415 num_new ++;
416
417 if (num_new == num) {
418 /* same uris no need to update anything. */
419 g_strfreev (uris);
420 return;
421 }
422 }
423 }
424
425 /* if we are in the middle of an unfinished size seek then
426 * cancel it and re-initialize */
427 if (manager->priv->size_preview)
428 brasero_io_cancel_by_base (manager->priv->size_preview);
429
430 if (manager->priv->selected) {
431 g_strfreev (manager->priv->selected);
432 manager->priv->selected = NULL;
433 }
434
435 if (manager->priv->preview_id) {
436 g_source_remove (manager->priv->preview_id);
437 manager->priv->preview_id = 0;
438 }
439
440 manager->priv->selected = uris;
441 if (!manager->priv->selected) {
442 GtkWidget *status;
443
444 status = brasero_app_get_statusbar1 (brasero_app_get_default ());
445
446 if (!manager->priv->status_ctx)
447 manager->priv->status_ctx = gtk_statusbar_get_context_id (GTK_STATUSBAR (status),
448 "size_info");
449
450 gtk_statusbar_pop (GTK_STATUSBAR (status), manager->priv->status_ctx);
451 gtk_statusbar_push (GTK_STATUSBAR (status),
452 manager->priv->status_ctx,
453 _("No file selected"));
454 return;
455 }
456
457 manager->priv->preview_id = g_timeout_add (500,
458 brasero_project_manager_selected_uris_preview,
459 manager);
460 }
461
462 static void
brasero_project_manager_sidepane_changed(BraseroLayout * layout,gboolean visible,BraseroProjectManager * manager)463 brasero_project_manager_sidepane_changed (BraseroLayout *layout,
464 gboolean visible,
465 BraseroProjectManager *manager)
466 {
467 if (!visible) {
468 GtkWidget *status;
469
470 /* If sidepane is disabled, remove any text about selection */
471 if (manager->priv->size_preview)
472 brasero_io_cancel_by_base (manager->priv->size_preview);
473
474 status = brasero_app_get_statusbar1 (brasero_app_get_default ());
475
476 gtk_statusbar_pop (GTK_STATUSBAR (status), manager->priv->status_ctx);
477
478 if (manager->priv->selected) {
479 g_strfreev (manager->priv->selected);
480 manager->priv->selected = NULL;
481 }
482
483 if (manager->priv->preview_id) {
484 g_source_remove (manager->priv->preview_id);
485 manager->priv->preview_id = 0;
486 }
487 }
488 }
489
490 void
brasero_project_manager_register_ui(BraseroProjectManager * manager,GtkUIManager * ui_manager)491 brasero_project_manager_register_ui (BraseroProjectManager *manager,
492 GtkUIManager *ui_manager)
493 {
494 GError *error = NULL;
495
496 gtk_ui_manager_insert_action_group (ui_manager, manager->priv->action_group, 0);
497 if (!gtk_ui_manager_add_ui_from_string (ui_manager, description, -1, &error)) {
498 g_message ("building UI failed: %s", error->message);
499 g_error_free (error);
500 }
501
502 brasero_project_register_ui (BRASERO_PROJECT (manager->priv->project), ui_manager);
503 brasero_layout_register_ui (BRASERO_LAYOUT (manager->priv->layout), ui_manager);
504 }
505
506 void
brasero_project_manager_switch(BraseroProjectManager * manager,BraseroProjectType type,gboolean reset)507 brasero_project_manager_switch (BraseroProjectManager *manager,
508 BraseroProjectType type,
509 gboolean reset)
510 {
511 GtkWidget *toplevel;
512 GtkAction *action;
513
514 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (manager));
515
516 if (manager->priv->type == BRASERO_PROJECT_TYPE_AUDIO
517 || manager->priv->type == BRASERO_PROJECT_TYPE_DATA
518 || manager->priv->type == BRASERO_PROJECT_TYPE_VIDEO) {
519 BraseroBurnResult result;
520 gboolean keep_files = FALSE;
521
522 if (type == BRASERO_PROJECT_TYPE_AUDIO
523 || type == BRASERO_PROJECT_TYPE_DATA
524 || type == BRASERO_PROJECT_TYPE_VIDEO) {
525 if (manager->priv->type != type
526 && (((manager->priv->type == BRASERO_PROJECT_TYPE_AUDIO ||
527 manager->priv->type == BRASERO_PROJECT_TYPE_VIDEO) &&
528 type == BRASERO_PROJECT_TYPE_DATA)
529 || manager->priv->type == BRASERO_PROJECT_TYPE_DATA))
530 keep_files = TRUE;
531 }
532
533 result = brasero_project_confirm_switch (BRASERO_PROJECT (manager->priv->project), keep_files);
534 if (result == BRASERO_BURN_CANCEL)
535 return;
536
537 if (result == BRASERO_BURN_RETRY) {
538 if (manager->priv->type == BRASERO_PROJECT_TYPE_AUDIO
539 || manager->priv->type == BRASERO_PROJECT_TYPE_VIDEO)
540 type = brasero_project_convert_to_data (BRASERO_PROJECT (manager->priv->project));
541 else if (manager->priv->type == BRASERO_PROJECT_TYPE_DATA) {
542 BraseroProjectType new_type;
543
544 /* Keep type untouched */
545 new_type = brasero_project_convert_to_stream (BRASERO_PROJECT (manager->priv->project),
546 type == BRASERO_PROJECT_TYPE_VIDEO);
547 if (new_type == BRASERO_PROJECT_TYPE_INVALID)
548 type = new_type;
549 }
550
551 if (type != BRASERO_PROJECT_TYPE_INVALID)
552 reset = FALSE;
553 else
554 reset = TRUE;
555 }
556 }
557
558 if (manager->priv->status_ctx) {
559 GtkWidget *status;
560
561 status = brasero_app_get_statusbar1 (brasero_app_get_default ());
562 gtk_statusbar_pop (GTK_STATUSBAR (status), manager->priv->status_ctx);
563 }
564
565 action = gtk_action_group_get_action (manager->priv->action_group, "NewChoose");
566
567 manager->priv->type = type;
568 if (type == BRASERO_PROJECT_TYPE_INVALID) {
569 brasero_layout_load (BRASERO_LAYOUT (manager->priv->layout), BRASERO_LAYOUT_NONE);
570 brasero_project_set_none (BRASERO_PROJECT (manager->priv->project));
571
572 gtk_notebook_set_current_page (GTK_NOTEBOOK (manager), 0);
573 gtk_action_set_sensitive (action, FALSE);
574
575 if (toplevel)
576 gtk_window_set_title (GTK_WINDOW (toplevel), "Brasero");
577 }
578 else if (type == BRASERO_PROJECT_TYPE_AUDIO) {
579 brasero_layout_load (BRASERO_LAYOUT (manager->priv->layout), BRASERO_LAYOUT_AUDIO);
580
581 gtk_notebook_set_current_page (GTK_NOTEBOOK (manager), 1);
582 gtk_action_set_sensitive (action, TRUE);
583
584 if (reset) {
585 /* tell the BraseroProject object that we want an audio selection */
586 brasero_project_set_audio (BRASERO_PROJECT (manager->priv->project));
587 }
588
589 if (toplevel)
590 gtk_window_set_title (GTK_WINDOW (toplevel), _("Brasero — New Audio Disc Project"));
591 }
592 else if (type == BRASERO_PROJECT_TYPE_DATA) {
593 brasero_layout_load (BRASERO_LAYOUT (manager->priv->layout), BRASERO_LAYOUT_DATA);
594
595 gtk_notebook_set_current_page (GTK_NOTEBOOK (manager), 1);
596 gtk_action_set_sensitive (action, TRUE);
597
598 if (reset) {
599 /* tell the BraseroProject object that we want a data selection */
600 brasero_project_set_data (BRASERO_PROJECT (manager->priv->project));
601 }
602
603 if (toplevel)
604 gtk_window_set_title (GTK_WINDOW (toplevel), _("Brasero — New Data Disc Project"));
605 }
606 else if (type == BRASERO_PROJECT_TYPE_VIDEO) {
607 brasero_layout_load (BRASERO_LAYOUT (manager->priv->layout), BRASERO_LAYOUT_VIDEO);
608
609 gtk_notebook_set_current_page (GTK_NOTEBOOK (manager), 1);
610 gtk_action_set_sensitive (action, TRUE);
611
612 if (reset) {
613 /* tell the BraseroProject object that we want a data selection */
614 brasero_project_set_video (BRASERO_PROJECT (manager->priv->project));
615 }
616
617 if (toplevel)
618 gtk_window_set_title (GTK_WINDOW (toplevel), _("Brasero — New Video Disc Project"));
619 }
620 else if (type == BRASERO_PROJECT_TYPE_ISO) {
621 brasero_layout_load (BRASERO_LAYOUT (manager->priv->layout), BRASERO_LAYOUT_NONE);
622 brasero_project_set_none (BRASERO_PROJECT (manager->priv->project));
623
624 gtk_notebook_set_current_page (GTK_NOTEBOOK (manager), 0);
625 gtk_action_set_sensitive (action, FALSE);
626
627 if (toplevel)
628 gtk_window_set_title (GTK_WINDOW (toplevel), _("Brasero — New Image File"));
629
630 brasero_project_manager_switch (manager,
631 BRASERO_PROJECT_TYPE_INVALID,
632 TRUE);
633 brasero_app_image (brasero_app_get_default (), NULL, NULL, FALSE);
634 }
635 else if (type == BRASERO_PROJECT_TYPE_COPY) {
636 brasero_layout_load (BRASERO_LAYOUT (manager->priv->layout), BRASERO_LAYOUT_NONE);
637 brasero_project_set_none (BRASERO_PROJECT (manager->priv->project));
638
639 gtk_notebook_set_current_page (GTK_NOTEBOOK (manager), 0);
640 gtk_action_set_sensitive (action, FALSE);
641
642 if (toplevel)
643 gtk_window_set_title (GTK_WINDOW (toplevel), _("Brasero — Disc Copy"));
644
645 brasero_project_manager_switch (manager,
646 BRASERO_PROJECT_TYPE_INVALID,
647 TRUE);
648 brasero_app_copy_disc (brasero_app_get_default (), NULL, NULL, NULL, FALSE);
649 }
650 }
651
652 static void
brasero_project_manager_type_changed_cb(BraseroProjectTypeChooser * chooser,BraseroProjectType type,BraseroProjectManager * manager)653 brasero_project_manager_type_changed_cb (BraseroProjectTypeChooser *chooser,
654 BraseroProjectType type,
655 BraseroProjectManager *manager)
656 {
657 brasero_project_manager_switch (manager, type, TRUE);
658 }
659
660 static void
brasero_project_manager_new_empty_prj_cb(GtkAction * action,BraseroProjectManager * manager)661 brasero_project_manager_new_empty_prj_cb (GtkAction *action, BraseroProjectManager *manager)
662 {
663 brasero_project_manager_switch (manager, BRASERO_PROJECT_TYPE_INVALID, TRUE);
664 }
665
666 static void
brasero_project_manager_new_audio_prj_cb(GtkAction * action,BraseroProjectManager * manager)667 brasero_project_manager_new_audio_prj_cb (GtkAction *action, BraseroProjectManager *manager)
668 {
669 brasero_project_manager_switch (manager, BRASERO_PROJECT_TYPE_AUDIO, TRUE);
670 }
671
672 static void
brasero_project_manager_new_data_prj_cb(GtkAction * action,BraseroProjectManager * manager)673 brasero_project_manager_new_data_prj_cb (GtkAction *action, BraseroProjectManager *manager)
674 {
675 brasero_project_manager_switch (manager, BRASERO_PROJECT_TYPE_DATA, TRUE);
676 }
677
678 static void
brasero_project_manager_new_video_prj_cb(GtkAction * action,BraseroProjectManager * manager)679 brasero_project_manager_new_video_prj_cb (GtkAction *action, BraseroProjectManager *manager)
680 {
681 brasero_project_manager_switch (manager, BRASERO_PROJECT_TYPE_VIDEO, TRUE);
682 }
683
684 static void
brasero_project_manager_new_copy_prj_cb(GtkAction * action,BraseroProjectManager * manager)685 brasero_project_manager_new_copy_prj_cb (GtkAction *action, BraseroProjectManager *manager)
686 {
687 brasero_project_manager_switch (manager, BRASERO_PROJECT_TYPE_COPY, TRUE);
688 }
689
690 static void
brasero_project_manager_new_iso_prj_cb(GtkAction * action,BraseroProjectManager * manager)691 brasero_project_manager_new_iso_prj_cb (GtkAction *action, BraseroProjectManager *manager)
692 {
693 brasero_project_manager_switch (manager, BRASERO_PROJECT_TYPE_ISO, TRUE);
694 }
695
696 gboolean
brasero_project_manager_open_session(BraseroProjectManager * manager,BraseroSessionCfg * session)697 brasero_project_manager_open_session (BraseroProjectManager *manager,
698 BraseroSessionCfg *session)
699 {
700 GtkAction *action;
701 BraseroProjectType type;
702
703 type = brasero_project_open_session (BRASERO_PROJECT (manager->priv->project), session);
704 if (type == BRASERO_PROJECT_TYPE_INVALID) {
705 brasero_project_manager_switch (manager, BRASERO_PROJECT_TYPE_INVALID, TRUE);
706 return FALSE;
707 }
708
709 brasero_project_manager_switch (manager,
710 type,
711 FALSE);
712
713 action = gtk_action_group_get_action (manager->priv->action_group, "NewChoose");
714 gtk_action_set_sensitive (action, TRUE);
715 return TRUE;
716 }
717
718 static void
brasero_project_manager_open_cb(GtkAction * action,BraseroProjectManager * manager)719 brasero_project_manager_open_cb (GtkAction *action, BraseroProjectManager *manager)
720 {
721 gchar *uri;
722 gint answer;
723 GtkWidget *chooser;
724 GtkWidget *toplevel;
725
726 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (manager));
727 chooser = gtk_file_chooser_dialog_new (_("Open Project"),
728 GTK_WINDOW (toplevel),
729 GTK_FILE_CHOOSER_ACTION_OPEN,
730 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
731 GTK_STOCK_OPEN, GTK_RESPONSE_OK,
732 NULL);
733 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE);
734 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
735 g_get_home_dir ());
736
737 gtk_widget_show (chooser);
738 answer = gtk_dialog_run (GTK_DIALOG (chooser));
739 if (answer != GTK_RESPONSE_OK) {
740 gtk_widget_destroy (chooser);
741 return;
742 }
743
744 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (chooser));
745 gtk_widget_destroy (chooser);
746
747 brasero_app_open_uri (brasero_app_get_default (), uri, TRUE);
748 g_free (uri);
749 }
750
751 static void
brasero_project_manager_recent_clicked_cb(BraseroProjectTypeChooser * chooser,const gchar * uri,BraseroProjectManager * manager)752 brasero_project_manager_recent_clicked_cb (BraseroProjectTypeChooser *chooser,
753 const gchar *uri,
754 BraseroProjectManager *manager)
755 {
756 brasero_app_open_uri (brasero_app_get_default (), uri, TRUE);
757 }
758
759 void
brasero_project_manager_empty(BraseroProjectManager * manager)760 brasero_project_manager_empty (BraseroProjectManager *manager)
761 {
762 brasero_project_manager_switch (manager, BRASERO_PROJECT_TYPE_INVALID, TRUE);
763 }
764
765 static void
brasero_project_manager_last_saved_clicked_cb(BraseroProjectTypeChooser * chooser,const gchar * path,BraseroProjectManager * manager)766 brasero_project_manager_last_saved_clicked_cb (BraseroProjectTypeChooser *chooser,
767 const gchar *path,
768 BraseroProjectManager *manager)
769 {
770 if (path) {
771 gchar *uri;
772
773 uri = g_filename_to_uri (path, NULL, NULL);
774 brasero_app_open_project (brasero_app_get_default (),
775 NULL,
776 uri,
777 FALSE, // not a playlist
778 FALSE, // should work so don't warn user
779 FALSE); // don't burn right away
780 g_free (uri);
781 }
782 }
783
784 gboolean
brasero_project_manager_save_session(BraseroProjectManager * manager,const gchar * path,gchar ** saved_uri,gboolean cancellable)785 brasero_project_manager_save_session (BraseroProjectManager *manager,
786 const gchar *path,
787 gchar **saved_uri,
788 gboolean cancellable)
789 {
790 gboolean result = FALSE;
791
792 if (path) {
793 gchar *uri;
794
795 /* if we want to save the current open project, this need a
796 * modification in BraseroProject to bypass ask_status in case
797 * DataDisc has not finished exploration */
798 uri = g_filename_to_uri (path, NULL, NULL);
799 result = brasero_project_save_session (BRASERO_PROJECT (manager->priv->project),
800 uri,
801 saved_uri,
802 cancellable);
803 g_free (uri);
804 }
805
806 return result;
807 }
808
809 static void
brasero_project_manager_init(BraseroProjectManager * obj)810 brasero_project_manager_init (BraseroProjectManager *obj)
811 {
812 GtkWidget *type;
813 GtkAction *action;
814 GtkWidget *chooser;
815
816 obj->priv = g_new0 (BraseroProjectManagerPrivate, 1);
817
818 gtk_notebook_set_show_border (GTK_NOTEBOOK (obj), FALSE);
819 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (obj), FALSE);
820
821 obj->priv->action_group = gtk_action_group_new ("ProjectManagerAction");
822 gtk_action_group_set_translation_domain (obj->priv->action_group, GETTEXT_PACKAGE);
823 gtk_action_group_add_actions (obj->priv->action_group,
824 entries,
825 G_N_ELEMENTS (entries),
826 obj);
827
828 action = gtk_action_group_get_action (obj->priv->action_group, "NewChoose");
829 g_object_set (action,
830 "short-label", _("_New"), /* for toolbar buttons */
831 NULL);
832 action = gtk_action_group_get_action (obj->priv->action_group, "Open");
833 g_object_set (action,
834 "short-label", _("_Open"), /* for toolbar buttons */
835 NULL);
836
837 /* add the project type chooser to the notebook */
838 type = brasero_project_type_chooser_new ();
839 gtk_widget_show (type);
840 g_signal_connect (type,
841 "chosen",
842 G_CALLBACK (brasero_project_manager_type_changed_cb),
843 obj);
844 g_signal_connect (type,
845 "recent-clicked",
846 G_CALLBACK (brasero_project_manager_recent_clicked_cb),
847 obj);
848 g_signal_connect (type,
849 "last-saved",
850 G_CALLBACK (brasero_project_manager_last_saved_clicked_cb),
851 obj);
852 gtk_notebook_prepend_page (GTK_NOTEBOOK (obj), type, NULL);
853
854 /* add the layout */
855 obj->priv->layout = brasero_layout_new ();
856 gtk_widget_show (obj->priv->layout);
857 gtk_notebook_append_page (GTK_NOTEBOOK (obj), obj->priv->layout, NULL);
858
859 g_signal_connect (obj->priv->layout,
860 "sidepane",
861 G_CALLBACK (brasero_project_manager_sidepane_changed),
862 obj);
863
864 /* create the project for audio and data discs */
865 obj->priv->project = brasero_project_new ();
866
867 #ifdef BUILD_PREVIEW
868
869 GtkWidget *preview;
870
871 preview = brasero_preview_new ();
872 gtk_widget_show (preview);
873 brasero_preview_add_source (BRASERO_PREVIEW (preview),
874 BRASERO_URI_CONTAINER (obj->priv->project));
875
876 #endif /* BUILD_PREVIEW */
877
878 chooser = brasero_file_chooser_new ();
879 BRASERO_PROJECT_MANAGER_CONNECT_CHANGED (obj, chooser);
880
881 gtk_widget_show_all (chooser);
882 brasero_layout_add_source (BRASERO_LAYOUT (obj->priv->layout),
883 chooser,
884 "Chooser",
885 _("Browse the file system"),
886 GTK_STOCK_DIRECTORY,
887 BRASERO_LAYOUT_AUDIO|BRASERO_LAYOUT_DATA|BRASERO_LAYOUT_VIDEO);
888
889 #ifdef BUILD_PREVIEW
890 brasero_preview_add_source (BRASERO_PREVIEW (preview),
891 BRASERO_URI_CONTAINER (chooser));
892 #endif
893
894 brasero_layout_add_project (BRASERO_LAYOUT (obj->priv->layout),
895 obj->priv->project);
896 gtk_widget_show (obj->priv->project);
897
898 #ifdef BUILD_PLAYLIST
899 GtkWidget *playlist;
900
901 playlist = brasero_playlist_new ();
902 BRASERO_PROJECT_MANAGER_CONNECT_CHANGED (obj, playlist);
903 gtk_widget_show_all (playlist);
904 brasero_layout_add_source (BRASERO_LAYOUT (obj->priv->layout),
905 playlist,
906 "Playlist",
907 _("Display playlists and their contents"),
908 "audio-x-generic",
909 BRASERO_LAYOUT_AUDIO);
910
911 #ifdef BUILD_PREVIEW
912 brasero_preview_add_source (BRASERO_PREVIEW (preview),
913 BRASERO_URI_CONTAINER (playlist));
914 #endif
915
916 #endif /* BUILD_PLAYLIST */
917
918 #ifdef BUILD_PREVIEW
919 brasero_layout_add_preview (BRASERO_LAYOUT (obj->priv->layout),
920 preview);
921 #endif
922
923 }
924
925 static void
brasero_project_manager_finalize(GObject * object)926 brasero_project_manager_finalize (GObject *object)
927 {
928 BraseroProjectManager *cobj;
929
930 cobj = BRASERO_PROJECT_MANAGER (object);
931
932 if (cobj->priv->size_preview) {
933 brasero_io_cancel_by_base (cobj->priv->size_preview);
934 brasero_io_job_base_free (cobj->priv->size_preview);
935 cobj->priv->size_preview = NULL;
936 }
937
938 if (cobj->priv->preview_id) {
939 g_source_remove (cobj->priv->preview_id);
940 cobj->priv->preview_id = 0;
941 }
942
943 if (cobj->priv->selected) {
944 g_strfreev (cobj->priv->selected);
945 cobj->priv->selected = NULL;
946 }
947
948 g_free (cobj->priv);
949
950 G_OBJECT_CLASS (parent_class)->finalize (object);
951 }
952
953 static void
brasero_project_manager_class_init(BraseroProjectManagerClass * klass)954 brasero_project_manager_class_init (BraseroProjectManagerClass *klass)
955 {
956 GObjectClass *object_class = G_OBJECT_CLASS(klass);
957
958 parent_class = g_type_class_peek_parent(klass);
959 object_class->finalize = brasero_project_manager_finalize;
960 }
961
962 GtkWidget *
brasero_project_manager_new()963 brasero_project_manager_new ()
964 {
965 BraseroProjectManager *obj;
966
967 obj = BRASERO_PROJECT_MANAGER (g_object_new (BRASERO_TYPE_PROJECT_MANAGER, NULL));
968
969 return GTK_WIDGET (obj);
970 }
971