~mfisch/brasero/update-to-3.8.0

« back to all changes in this revision

Viewing changes to libbrasero-burn/brasero-data-session.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Ancell
  • Date: 2009-06-03 10:36:30 UTC
  • mfrom: (1.1.23 upstream)
  • Revision ID: james.westby@ubuntu.com-20090603103630-2r72408gk45sc0ws
Tags: 2.27.2-0ubuntu1
* New upstream release (LP: #380850)
  - Split burning backend into a new library called libbrasero-burn
  - Split some utilities into a new library called libbrasero-utils
  - Use Brasero as a single instance application using libunique
  - Data spanning
  - Memleak fixes
  - Bug Fixes
  - String fixes
  - Use autogenerated Changelog via git
  - Translation Updates
  - Fixes (LP: #360671)
* Bump GTK+ requirement and add libunique requirement

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 
2
/*
 
3
 * Libbrasero-burn
 
4
 * Copyright (C) Philippe Rouquier 2005-2009 <bonfire-app@wanadoo.fr>
 
5
 *
 
6
 * Libbrasero-burn is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * The Libbrasero-burn authors hereby grant permission for non-GPL compatible
 
12
 * GStreamer plugins to be used and distributed together with GStreamer
 
13
 * and Libbrasero-burn. This permission is above and beyond the permissions granted
 
14
 * by the GPL license by which Libbrasero-burn is covered. If you modify this code
 
15
 * you may extend this exception to your version of the code, but you are not
 
16
 * obligated to do so. If you do not wish to do so, delete this exception
 
17
 * statement from your version.
 
18
 * 
 
19
 * Libbrasero-burn is distributed in the hope that it will be useful,
 
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
22
 * GNU Library General Public License for more details.
 
23
 * 
 
24
 * You should have received a copy of the GNU General Public License
 
25
 * along with this program; if not, write to:
 
26
 *      The Free Software Foundation, Inc.,
 
27
 *      51 Franklin Street, Fifth Floor
 
28
 *      Boston, MA  02110-1301, USA.
 
29
 */
 
30
 
 
31
#ifdef HAVE_CONFIG_H
 
32
#  include <config.h>
 
33
#endif
 
34
 
 
35
#include <glib.h>
 
36
#include <glib/gi18n-lib.h>
 
37
 
 
38
#include "brasero-media-private.h"
 
39
 
 
40
#include "scsi-device.h"
 
41
 
 
42
#include "brasero-drive.h"
 
43
#include "brasero-medium.h"
 
44
#include "brasero-medium-monitor.h"
 
45
#include "burn-volume.h"
 
46
 
 
47
#include "brasero-burn-lib.h"
 
48
 
 
49
#include "brasero-data-session.h"
 
50
#include "brasero-data-project.h"
 
51
#include "brasero-file-node.h"
 
52
#include "brasero-io.h"
 
53
 
 
54
#include "libbrasero-marshal.h"
 
55
 
 
56
typedef struct _BraseroDataSessionPrivate BraseroDataSessionPrivate;
 
57
struct _BraseroDataSessionPrivate
 
58
{
 
59
        BraseroIOJobBase *load_dir;
 
60
 
 
61
        /* Multisession drives that are inserted */
 
62
        GSList *media;
 
63
 
 
64
        /* Drive whose session is loaded */
 
65
        BraseroMedium *loaded;
 
66
 
 
67
        /* Nodes from the loaded session in the tree */
 
68
        GSList *nodes;
 
69
 
 
70
        glong size_changed_sig;
 
71
 
 
72
        guint is_oversized:1;
 
73
        guint is_overburn:1;
 
74
};
 
75
 
 
76
#define BRASERO_DATA_SESSION_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_DATA_SESSION, BraseroDataSessionPrivate))
 
77
 
 
78
G_DEFINE_TYPE (BraseroDataSession, brasero_data_session, BRASERO_TYPE_DATA_PROJECT);
 
79
 
 
80
enum {
 
81
        OVERSIZE_SIGNAL,
 
82
        AVAILABLE_SIGNAL,
 
83
        LOADED_SIGNAL,
 
84
        LAST_SIGNAL
 
85
};
 
86
 
 
87
static gulong brasero_data_session_signals [LAST_SIGNAL] = { 0 };
 
88
 
 
89
/**
 
90
 * to evaluate the contents of a medium or image async
 
91
 */
 
92
struct _BraseroIOImageContentsData {
 
93
        BraseroIOJob job;
 
94
        gchar *dev_image;
 
95
 
 
96
        gint64 session_block;
 
97
        gint64 block;
 
98
};
 
99
typedef struct _BraseroIOImageContentsData BraseroIOImageContentsData;
 
100
 
 
101
static void
 
102
brasero_io_image_directory_contents_destroy (BraseroAsyncTaskManager *manager,
 
103
                                             gboolean cancelled,
 
104
                                             gpointer callback_data)
 
105
{
 
106
        BraseroIOImageContentsData *data = callback_data;
 
107
 
 
108
        g_free (data->dev_image);
 
109
        brasero_io_job_free (cancelled, BRASERO_IO_JOB (data));
 
110
}
 
111
 
 
112
static BraseroAsyncTaskResult
 
113
brasero_io_image_directory_contents_thread (BraseroAsyncTaskManager *manager,
 
114
                                            GCancellable *cancel,
 
115
                                            gpointer callback_data)
 
116
{
 
117
        BraseroIOImageContentsData *data = callback_data;
 
118
        BraseroDeviceHandle *handle;
 
119
        GList *children, *iter;
 
120
        GError *error = NULL;
 
121
        BraseroVolSrc *vol;
 
122
 
 
123
        handle = brasero_device_handle_open (data->job.uri, FALSE, NULL);
 
124
        vol = brasero_volume_source_open_device_handle (handle, &error);
 
125
        if (!vol) {
 
126
                brasero_device_handle_close (handle);
 
127
                brasero_io_return_result (data->job.base,
 
128
                                          data->job.uri,
 
129
                                          NULL,
 
130
                                          error,
 
131
                                          data->job.callback_data);
 
132
                return BRASERO_ASYNC_TASK_FINISHED;
 
133
        }
 
134
 
 
135
        children = brasero_volume_load_directory_contents (vol,
 
136
                                                           data->session_block,
 
137
                                                           data->block,
 
138
                                                           &error);
 
139
        brasero_volume_source_close (vol);
 
140
        brasero_device_handle_close (handle);
 
141
 
 
142
        for (iter = children; iter; iter = iter->next) {
 
143
                BraseroVolFile *file;
 
144
                GFileInfo *info;
 
145
 
 
146
                file = iter->data;
 
147
 
 
148
                info = g_file_info_new ();
 
149
                g_file_info_set_file_type (info, file->isdir? G_FILE_TYPE_DIRECTORY:G_FILE_TYPE_REGULAR);
 
150
                g_file_info_set_name (info, BRASERO_VOLUME_FILE_NAME (file));
 
151
 
 
152
                if (file->isdir)
 
153
                        g_file_info_set_attribute_int64 (info,
 
154
                                                         BRASERO_IO_DIR_CONTENTS_ADDR,
 
155
                                                         file->specific.dir.address);
 
156
                else
 
157
                        g_file_info_set_size (info, BRASERO_VOLUME_FILE_SIZE (file));
 
158
 
 
159
                brasero_io_return_result (data->job.base,
 
160
                                          data->job.uri,
 
161
                                          info,
 
162
                                          NULL,
 
163
                                          data->job.callback_data);
 
164
        }
 
165
 
 
166
        g_list_foreach (children, (GFunc) brasero_volume_file_free, NULL);
 
167
        g_list_free (children);
 
168
 
 
169
        return BRASERO_ASYNC_TASK_FINISHED;
 
170
}
 
171
 
 
172
static const BraseroAsyncTaskType image_contents_type = {
 
173
        brasero_io_image_directory_contents_thread,
 
174
        brasero_io_image_directory_contents_destroy
 
175
};
 
176
 
 
177
void
 
178
brasero_io_load_image_directory (const gchar *dev_image,
 
179
                                 gint64 session_block,
 
180
                                 gint64 block,
 
181
                                 const BraseroIOJobBase *base,
 
182
                                 BraseroIOFlags options,
 
183
                                 gpointer user_data)
 
184
{
 
185
        BraseroIOImageContentsData *data;
 
186
        BraseroIOResultCallbackData *callback_data = NULL;
 
187
 
 
188
        if (user_data) {
 
189
                callback_data = g_new0 (BraseroIOResultCallbackData, 1);
 
190
                callback_data->callback_data = user_data;
 
191
        }
 
192
 
 
193
        data = g_new0 (BraseroIOImageContentsData, 1);
 
194
        data->block = block;
 
195
        data->session_block = session_block;
 
196
 
 
197
        brasero_io_set_job (BRASERO_IO_JOB (data),
 
198
                            base,
 
199
                            dev_image,
 
200
                            options,
 
201
                            callback_data);
 
202
 
 
203
        brasero_io_push_job (BRASERO_IO_JOB (data),
 
204
                             &image_contents_type);
 
205
 
 
206
}
 
207
 
 
208
static void
 
209
brasero_data_session_check_size (BraseroDataSession *self)
 
210
{
 
211
        BraseroDataSessionPrivate *priv;
 
212
        gint64 max_sectors = 0;
 
213
        gint64 medium_sect = 0;
 
214
        goffset sectors = 0;
 
215
 
 
216
        priv = BRASERO_DATA_SESSION_PRIVATE (self);
 
217
 
 
218
        sectors = brasero_data_project_get_sectors (BRASERO_DATA_PROJECT (self));
 
219
        brasero_medium_get_free_space (priv->loaded,
 
220
                                       NULL,
 
221
                                       &medium_sect);
 
222
 
 
223
        /* NOTE: This is not good since with a DVD 3% of 4.3G may be too much
 
224
         * with 3% we are slightly over the limit of the most overburnable discs
 
225
         * but at least users can try to overburn as much as they can. */
 
226
 
 
227
        /* The idea would be to test write the disc with cdrecord from /dev/null
 
228
         * until there is an error and see how much we were able to write. So,
 
229
         * when we propose overburning to the user, we could ask if he wants
 
230
         * us to determine how much data can be written to a particular disc
 
231
         * provided he has chosen a real disc. */
 
232
        max_sectors = medium_sect * 103 / 100;
 
233
 
 
234
        if (medium_sect < sectors) {
 
235
                /* send it once */
 
236
                if (!priv->is_oversized || priv->is_overburn) {
 
237
                        gboolean overburn;
 
238
 
 
239
                        /* see if overburn is possible */
 
240
                        overburn = (sectors < max_sectors);
 
241
                        if (!priv->is_overburn && overburn)
 
242
                                g_signal_emit (self,
 
243
                                               brasero_data_session_signals [OVERSIZE_SIGNAL],
 
244
                                               0,
 
245
                                               TRUE,
 
246
                                               overburn);
 
247
                        else if (!overburn)
 
248
                                g_signal_emit (self,
 
249
                                               brasero_data_session_signals [OVERSIZE_SIGNAL],
 
250
                                               0,
 
251
                                               TRUE,
 
252
                                               overburn);
 
253
 
 
254
                        priv->is_overburn = overburn;
 
255
                }
 
256
 
 
257
                priv->is_oversized = TRUE;
 
258
        }
 
259
        else {
 
260
                if (priv->is_oversized || priv->is_overburn)
 
261
                        g_signal_emit (self,
 
262
                                       brasero_data_session_signals [OVERSIZE_SIGNAL],
 
263
                                       0,
 
264
                                       FALSE,
 
265
                                       FALSE);
 
266
 
 
267
                priv->is_oversized = FALSE;
 
268
                priv->is_overburn = FALSE;
 
269
        }
 
270
}
 
271
 
 
272
static void
 
273
brasero_data_session_size_changed (BraseroDataProject *project,
 
274
                                   gpointer NULL_data)
 
275
{
 
276
        brasero_data_session_check_size (BRASERO_DATA_SESSION (project));
 
277
}
 
278
 
 
279
void
 
280
brasero_data_session_remove_last (BraseroDataSession *self)
 
281
{
 
282
        BraseroDataSessionPrivate *priv;
 
283
        GSList *iter;
 
284
 
 
285
        priv = BRASERO_DATA_SESSION_PRIVATE (self);
 
286
 
 
287
        if (!priv->nodes)
 
288
                return;
 
289
 
 
290
        /* go through the top nodes and remove all the imported nodes */
 
291
        for (iter = priv->nodes; iter; iter = iter->next) {
 
292
                BraseroFileNode *node;
 
293
 
 
294
                node = iter->data;
 
295
                brasero_data_project_destroy_node (BRASERO_DATA_PROJECT (self), node);
 
296
        }
 
297
 
 
298
        g_slist_free (priv->nodes);
 
299
        priv->nodes = NULL;
 
300
 
 
301
        g_signal_emit (self,
 
302
                       brasero_data_session_signals [LOADED_SIGNAL],
 
303
                       0,
 
304
                       priv->loaded,
 
305
                       FALSE);
 
306
 
 
307
        if (priv->loaded) {
 
308
                g_object_unref (priv->loaded);
 
309
                priv->loaded = NULL;
 
310
        }
 
311
 
 
312
        if (priv->size_changed_sig) {
 
313
                g_signal_handler_disconnect (self, priv->size_changed_sig);
 
314
                priv->size_changed_sig = 0;
 
315
        }
 
316
 
 
317
        priv->is_oversized = FALSE;
 
318
        priv->is_overburn = FALSE;
 
319
}
 
320
 
 
321
static void
 
322
brasero_data_session_load_dir_destroy (GObject *object,
 
323
                                       gboolean cancelled,
 
324
                                       gpointer data)
 
325
{
 
326
        gint reference;
 
327
        BraseroFileNode *parent;
 
328
 
 
329
        /* reference */
 
330
        reference = GPOINTER_TO_INT (data);
 
331
        if (reference <= 0)
 
332
                return;
 
333
 
 
334
        parent = brasero_data_project_reference_get (BRASERO_DATA_PROJECT (object), reference);
 
335
        if (parent)
 
336
                parent->is_exploring = FALSE;
 
337
 
 
338
        brasero_data_project_reference_free (BRASERO_DATA_PROJECT (object), reference);
 
339
}
 
340
 
 
341
static void
 
342
brasero_data_session_load_dir_result (GObject *owner,
 
343
                                      GError *error,
 
344
                                      const gchar *dev_image,
 
345
                                      GFileInfo *info,
 
346
                                      gpointer data)
 
347
{
 
348
        BraseroDataSessionPrivate *priv;
 
349
        BraseroFileNode *parent;
 
350
        BraseroFileNode *node;
 
351
        gint reference;
 
352
 
 
353
        priv = BRASERO_DATA_SESSION_PRIVATE (owner);
 
354
 
 
355
        if (!info) {
 
356
                g_signal_emit (owner,
 
357
                               brasero_data_session_signals [LOADED_SIGNAL],
 
358
                               0,
 
359
                               priv->loaded,
 
360
                               FALSE);
 
361
 
 
362
                /* FIXME: tell the user the error message */
 
363
                return;
 
364
        }
 
365
 
 
366
        reference = GPOINTER_TO_INT (data);
 
367
        if (reference > 0)
 
368
                parent = brasero_data_project_reference_get (BRASERO_DATA_PROJECT (owner),
 
369
                                                             reference);
 
370
        else
 
371
                parent = NULL;
 
372
 
 
373
        /* add all the files/folders at the root of the session */
 
374
        node = brasero_data_project_add_imported_session_file (BRASERO_DATA_PROJECT (owner),
 
375
                                                               info,
 
376
                                                               parent);
 
377
        if (!node) {
 
378
                /* a problem ? */
 
379
                g_signal_emit (owner,
 
380
                               brasero_data_session_signals [LOADED_SIGNAL],
 
381
                               0,
 
382
                               priv->loaded,
 
383
                               FALSE);
 
384
                return;
 
385
        }
 
386
 
 
387
        /* Only if we're exploring root directory */
 
388
        if (!parent)
 
389
                priv->nodes = g_slist_prepend (priv->nodes, node);
 
390
 
 
391
        g_signal_emit (owner,
 
392
                       brasero_data_session_signals [LOADED_SIGNAL],
 
393
                       0,
 
394
                       priv->loaded,
 
395
                       TRUE);
 
396
}
 
397
 
 
398
static gboolean
 
399
brasero_data_session_load_directory_contents_real (BraseroDataSession *self,
 
400
                                                   BraseroFileNode *node,
 
401
                                                   GError **error)
 
402
{
 
403
        BraseroDataSessionPrivate *priv;
 
404
        goffset session_block;
 
405
        const gchar *device;
 
406
        gint reference = -1;
 
407
 
 
408
        if (node && !node->is_fake)
 
409
                return TRUE;
 
410
 
 
411
        priv = BRASERO_DATA_SESSION_PRIVATE (self);
 
412
        device = brasero_drive_get_device (brasero_medium_get_drive (priv->loaded));
 
413
        brasero_medium_get_last_data_track_address (priv->loaded,
 
414
                                                    NULL,
 
415
                                                    &session_block);
 
416
 
 
417
        if (!priv->load_dir)
 
418
                priv->load_dir = brasero_io_register (G_OBJECT (self),
 
419
                                                      brasero_data_session_load_dir_result,
 
420
                                                      brasero_data_session_load_dir_destroy,
 
421
                                                      NULL);
 
422
 
 
423
        /* If there aren't any node then that's root */
 
424
        if (node) {
 
425
                reference = brasero_data_project_reference_new (BRASERO_DATA_PROJECT (self), node);
 
426
                node->is_exploring = TRUE;
 
427
        }
 
428
 
 
429
        brasero_io_load_image_directory (device,
 
430
                                         session_block,
 
431
                                         BRASERO_FILE_NODE_IMPORTED_ADDRESS (node),
 
432
                                         priv->load_dir,
 
433
                                         BRASERO_IO_INFO_URGENT,
 
434
                                         GINT_TO_POINTER (reference));
 
435
 
 
436
        if (node)
 
437
                node->is_fake = FALSE;
 
438
 
 
439
        return TRUE;
 
440
}
 
441
 
 
442
gboolean
 
443
brasero_data_session_load_directory_contents (BraseroDataSession *self,
 
444
                                              BraseroFileNode *node,
 
445
                                              GError **error)
 
446
{
 
447
        return brasero_data_session_load_directory_contents_real (self, node, error);
 
448
}
 
449
 
 
450
gboolean
 
451
brasero_data_session_add_last (BraseroDataSession *self,
 
452
                               BraseroMedium *medium,
 
453
                               GError **error)
 
454
{
 
455
        BraseroDataSessionPrivate *priv;
 
456
 
 
457
        priv = BRASERO_DATA_SESSION_PRIVATE (self);
 
458
        priv->loaded = medium;
 
459
        g_object_ref (medium);
 
460
 
 
461
        priv->size_changed_sig = g_signal_connect (self,
 
462
                                                   "size-changed",
 
463
                                                   G_CALLBACK (brasero_data_session_size_changed),
 
464
                                                   NULL);
 
465
 
 
466
        return brasero_data_session_load_directory_contents_real (self, NULL, error);
 
467
}
 
468
 
 
469
gboolean
 
470
brasero_data_session_has_available_media (BraseroDataSession *self)
 
471
{
 
472
        BraseroDataSessionPrivate *priv;
 
473
 
 
474
        priv = BRASERO_DATA_SESSION_PRIVATE (self);
 
475
 
 
476
        return priv->media != NULL;
 
477
}
 
478
 
 
479
GSList *
 
480
brasero_data_session_get_available_media (BraseroDataSession *self)
 
481
{
 
482
        GSList *retval;
 
483
        BraseroDataSessionPrivate *priv;
 
484
 
 
485
        priv = BRASERO_DATA_SESSION_PRIVATE (self);
 
486
 
 
487
        retval = g_slist_copy (priv->media);
 
488
        g_slist_foreach (retval, (GFunc) g_object_ref, NULL);
 
489
 
 
490
        return retval;
 
491
}
 
492
 
 
493
BraseroMedium *
 
494
brasero_data_session_get_loaded_medium (BraseroDataSession *self)
 
495
{
 
496
        BraseroDataSessionPrivate *priv;
 
497
 
 
498
        priv = BRASERO_DATA_SESSION_PRIVATE (self);
 
499
        if (!priv->media || !priv->nodes)
 
500
                return NULL;
 
501
 
 
502
        return priv->loaded;
 
503
}
 
504
 
 
505
static gboolean
 
506
brasero_data_session_is_valid_multi (BraseroMedium *medium)
 
507
{
 
508
        BraseroMedia media;
 
509
        BraseroMedia media_status;
 
510
 
 
511
        media = brasero_medium_get_status (medium);
 
512
        media_status = brasero_burn_library_get_media_capabilities (media);
 
513
 
 
514
        return (media_status & BRASERO_MEDIUM_WRITABLE) &&
 
515
               (media & BRASERO_MEDIUM_HAS_DATA) &&
 
516
               (brasero_medium_get_last_data_track_address (medium, NULL, NULL) != -1);
 
517
}
 
518
 
 
519
static void
 
520
brasero_data_session_disc_added_cb (BraseroMediumMonitor *monitor,
 
521
                                    BraseroMedium *medium,
 
522
                                    BraseroDataSession *self)
 
523
{
 
524
        BraseroDataSessionPrivate *priv;
 
525
 
 
526
        priv = BRASERO_DATA_SESSION_PRIVATE (self);
 
527
 
 
528
        if (!brasero_data_session_is_valid_multi (medium))
 
529
                return;
 
530
 
 
531
        g_object_ref (medium);
 
532
        priv->media = g_slist_prepend (priv->media, medium);
 
533
 
 
534
        g_signal_emit (self,
 
535
                       brasero_data_session_signals [AVAILABLE_SIGNAL],
 
536
                       0,
 
537
                       medium,
 
538
                       TRUE);
 
539
}
 
540
 
 
541
static void
 
542
brasero_data_session_disc_removed_cb (BraseroMediumMonitor *monitor,
 
543
                                      BraseroMedium *medium,
 
544
                                      BraseroDataSession *self)
 
545
{
 
546
        GSList *iter;
 
547
        GSList *next;
 
548
        BraseroDataSessionPrivate *priv;
 
549
 
 
550
        priv = BRASERO_DATA_SESSION_PRIVATE (self);
 
551
 
 
552
        /* see if that's the current loaded one */
 
553
        if (priv->loaded && priv->loaded == medium)
 
554
                brasero_data_session_remove_last (self);
 
555
 
 
556
        /* remove it from our list */
 
557
        for (iter = priv->media; iter; iter = next) {
 
558
                BraseroMedium *iter_medium;
 
559
 
 
560
                iter_medium = iter->data;
 
561
                next = iter->next;
 
562
 
 
563
                if (medium == iter_medium) {
 
564
                        g_signal_emit (self,
 
565
                                       brasero_data_session_signals [AVAILABLE_SIGNAL],
 
566
                                       0,
 
567
                                       medium,
 
568
                                       FALSE);
 
569
 
 
570
                        priv->media = g_slist_remove (priv->media, iter_medium);
 
571
                        g_object_unref (iter_medium);
 
572
                }
 
573
        }
 
574
}
 
575
 
 
576
static void
 
577
brasero_data_session_init (BraseroDataSession *object)
 
578
{
 
579
        GSList *iter, *list;
 
580
        BraseroMediumMonitor *monitor;
 
581
        BraseroDataSessionPrivate *priv;
 
582
 
 
583
        priv = BRASERO_DATA_SESSION_PRIVATE (object);
 
584
 
 
585
        monitor = brasero_medium_monitor_get_default ();
 
586
        g_signal_connect (monitor,
 
587
                          "medium-added",
 
588
                          G_CALLBACK (brasero_data_session_disc_added_cb),
 
589
                          object);
 
590
        g_signal_connect (monitor,
 
591
                          "medium-removed",
 
592
                          G_CALLBACK (brasero_data_session_disc_removed_cb),
 
593
                          object);
 
594
 
 
595
        list = brasero_medium_monitor_get_media (monitor,
 
596
                                                 BRASERO_MEDIA_TYPE_WRITABLE|
 
597
                                                 BRASERO_MEDIA_TYPE_REWRITABLE);
 
598
        g_object_unref (monitor);
 
599
 
 
600
        /* check for a multisession medium already in */
 
601
        for (iter = list; iter; iter = iter->next) {
 
602
                BraseroMedium *medium;
 
603
 
 
604
                medium = iter->data;
 
605
                if (brasero_data_session_is_valid_multi (medium)) {
 
606
                        g_object_ref (medium);
 
607
                        priv->media = g_slist_prepend (priv->media, medium);
 
608
                }
 
609
        }
 
610
        g_slist_foreach (list, (GFunc) g_object_unref, NULL);
 
611
        g_slist_free (list);
 
612
}
 
613
 
 
614
static void
 
615
brasero_data_session_stop_io (BraseroDataSession *self)
 
616
{
 
617
        BraseroDataSessionPrivate *priv;
 
618
 
 
619
        priv = BRASERO_DATA_SESSION_PRIVATE (self);
 
620
 
 
621
        if (priv->load_dir) {
 
622
                brasero_io_cancel_by_base (priv->load_dir);
 
623
                g_free (priv->load_dir);
 
624
                priv->load_dir = NULL;
 
625
        }
 
626
}
 
627
 
 
628
static void
 
629
brasero_data_session_reset (BraseroDataProject *project,
 
630
                            guint num_nodes)
 
631
{
 
632
        brasero_data_session_stop_io (BRASERO_DATA_SESSION (project));
 
633
 
 
634
        /* chain up this function except if we invalidated the node */
 
635
        if (BRASERO_DATA_PROJECT_CLASS (brasero_data_session_parent_class)->reset)
 
636
                BRASERO_DATA_PROJECT_CLASS (brasero_data_session_parent_class)->reset (project, num_nodes);
 
637
}
 
638
 
 
639
static void
 
640
brasero_data_session_finalize (GObject *object)
 
641
{
 
642
        BraseroDataSessionPrivate *priv;
 
643
 
 
644
        priv = BRASERO_DATA_SESSION_PRIVATE (object);
 
645
        if (priv->loaded) {
 
646
                g_object_unref (priv->loaded);
 
647
                priv->loaded = NULL;
 
648
        }
 
649
 
 
650
        if (priv->media) {
 
651
                g_slist_foreach (priv->media, (GFunc) g_object_unref, NULL);
 
652
                g_slist_free (priv->media);
 
653
                priv->media = NULL;
 
654
        }
 
655
 
 
656
        if (priv->nodes) {
 
657
                g_slist_free (priv->nodes);
 
658
                priv->nodes = NULL;
 
659
        }
 
660
 
 
661
        /* NOTE no need to clean up size_changed_sig since it's connected to 
 
662
         * ourselves. It disappears with use. */
 
663
 
 
664
        brasero_data_session_stop_io (BRASERO_DATA_SESSION (object));
 
665
 
 
666
        /* don't care about the nodes since they will be automatically
 
667
         * destroyed */
 
668
 
 
669
        G_OBJECT_CLASS (brasero_data_session_parent_class)->finalize (object);
 
670
}
 
671
 
 
672
 
 
673
static void
 
674
brasero_data_session_class_init (BraseroDataSessionClass *klass)
 
675
{
 
676
        GObjectClass* object_class = G_OBJECT_CLASS (klass);
 
677
        BraseroDataProjectClass *project_class = BRASERO_DATA_PROJECT_CLASS (klass);
 
678
 
 
679
        g_type_class_add_private (klass, sizeof (BraseroDataSessionPrivate));
 
680
 
 
681
        object_class->finalize = brasero_data_session_finalize;
 
682
 
 
683
        project_class->reset = brasero_data_session_reset;
 
684
 
 
685
        brasero_data_session_signals [AVAILABLE_SIGNAL] = 
 
686
            g_signal_new ("session_available",
 
687
                          G_TYPE_FROM_CLASS (klass),
 
688
                          G_SIGNAL_RUN_LAST,
 
689
                          0,
 
690
                          NULL, NULL,
 
691
                          brasero_marshal_VOID__OBJECT_BOOLEAN,
 
692
                          G_TYPE_NONE,
 
693
                          2,
 
694
                          G_TYPE_OBJECT,
 
695
                          G_TYPE_BOOLEAN);
 
696
        brasero_data_session_signals [LOADED_SIGNAL] = 
 
697
            g_signal_new ("session_loaded",
 
698
                          G_TYPE_FROM_CLASS (klass),
 
699
                          G_SIGNAL_RUN_LAST,
 
700
                          0,
 
701
                          NULL, NULL,
 
702
                          brasero_marshal_VOID__OBJECT_BOOLEAN,
 
703
                          G_TYPE_NONE,
 
704
                          2,
 
705
                          G_TYPE_OBJECT,
 
706
                          G_TYPE_BOOLEAN);
 
707
        brasero_data_session_signals [OVERSIZE_SIGNAL] = 
 
708
            g_signal_new ("oversize",
 
709
                          G_TYPE_FROM_CLASS (klass),
 
710
                          G_SIGNAL_RUN_LAST,
 
711
                          0,
 
712
                          NULL, NULL,
 
713
                          brasero_marshal_VOID__BOOLEAN_BOOLEAN,
 
714
                          G_TYPE_NONE,
 
715
                          2,
 
716
                          G_TYPE_BOOLEAN,
 
717
                          G_TYPE_BOOLEAN);
 
718
}