~ubuntu-branches/ubuntu/precise/rhythmbox/precise-201203091205

« back to all changes in this revision

Viewing changes to shell/rb-removable-media-manager.c

Tags: upstream-0.9.5
ImportĀ upstreamĀ versionĀ 0.9.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 *
17
17
 *  You should have received a copy of the GNU General Public License
18
18
 *  along with this program; if not, write to the Free Software
19
 
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
19
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
20
20
 *
21
21
 */
22
22
 
23
 
#include <config.h>
 
23
#include "config.h"
 
24
 
 
25
#include <string.h>
 
26
#include <glib/gi18n.h>
24
27
#include <gtk/gtk.h>
25
 
#include <libgnome/gnome-i18n.h>
 
28
 
26
29
#include <libgnomevfs/gnome-vfs.h>
 
30
 
27
31
#include <nautilus-burn-drive.h>
28
 
#include <string.h>
 
32
#ifndef NAUTILUS_BURN_CHECK_VERSION      
 
33
#define NAUTILUS_BURN_CHECK_VERSION(a,b,c) FALSE         
 
34
#endif
 
35
 
 
36
#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 
37
#include <nautilus-burn.h>
 
38
#endif
29
39
 
30
40
#include "rb-removable-media-manager.h"
 
41
#include "rb-library-source.h"
31
42
#include "rb-sourcelist.h"
32
43
#include "rb-removable-media-source.h"
33
 
#include "rb-generic-player-source.h"
34
44
#include "rb-audiocd-source.h"
35
 
#ifdef WITH_IPOD_SUPPORT
36
 
#include "rb-ipod-source.h"
37
 
#endif
38
45
 
 
46
#include "rb-shell.h"
 
47
#include "rb-shell-player.h"
39
48
#include "rb-debug.h"
40
49
#include "rb-dialog.h"
 
50
#include "rb-stock-icons.h"
41
51
#include "rhythmdb.h"
 
52
#include "rb-marshal.h"
 
53
#include "rb-util.h"
 
54
 
 
55
#ifdef ENABLE_TRACK_TRANSFER
 
56
#include "rb-encoder.h"
 
57
#endif
42
58
 
43
59
#ifndef HAVE_BURN_DRIVE_UNREF
44
60
#define nautilus_burn_drive_unref nautilus_burn_drive_free
47
63
static void rb_removable_media_manager_class_init (RBRemovableMediaManagerClass *klass);
48
64
static void rb_removable_media_manager_init (RBRemovableMediaManager *mgr);
49
65
static void rb_removable_media_manager_dispose (GObject *object);
 
66
static void rb_removable_media_manager_finalize (GObject *object);
50
67
static void rb_removable_media_manager_set_property (GObject *object,
51
68
                                              guint prop_id,
52
69
                                              const GValue *value,
76
93
static void  rb_removable_media_manager_volume_unmounted_cb (GnomeVFSVolumeMonitor *monitor,
77
94
                                GnomeVFSVolume *volume, 
78
95
                                gpointer data);
79
 
static void rb_removable_media_manager_scan (RBRemovableMediaManager *manager);
 
96
static gboolean rb_removable_media_manager_load_media (RBRemovableMediaManager *manager);
80
97
 
81
 
typedef struct
82
 
{
83
 
        gboolean removed;
84
 
        gboolean tray_opened;
85
 
        RBRemovableMediaManager *manager;
86
 
        NautilusBurnDrive *drive;
87
 
} RbCdDriveInfo;
 
98
#ifdef ENABLE_TRACK_TRANSFER
 
99
static void do_transfer (RBRemovableMediaManager *manager);
 
100
#endif
 
101
static void rb_removable_media_manager_cmd_copy_tracks (GtkAction *action,
 
102
                                                        RBRemovableMediaManager *mgr);
88
103
 
89
104
typedef struct
90
105
{
99
114
 
100
115
        GList *sources;
101
116
        GHashTable *volume_mapping;
 
117
#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3)
102
118
        GHashTable *cd_drive_mapping;
 
119
#endif
103
120
        GList *cur_volume_list;
 
121
        gboolean scanned;
 
122
 
 
123
        char *playing_uri;
 
124
 
 
125
        GAsyncQueue *transfer_queue;
 
126
        gboolean transfer_running;
 
127
        gint transfer_total;
 
128
        gint transfer_done;
 
129
        double transfer_fraction;
104
130
} RBRemovableMediaManagerPrivate;
105
131
 
106
132
G_DEFINE_TYPE (RBRemovableMediaManager, rb_removable_media_manager, G_TYPE_OBJECT)
112
138
        PROP_SHELL,
113
139
        PROP_SOURCELIST,
114
140
        PROP_SOURCE,
 
141
        PROP_SCANNED
115
142
};
116
143
 
117
144
enum
118
145
{
119
146
        MEDIUM_ADDED,
 
147
        TRANSFER_PROGRESS,
 
148
        CREATE_SOURCE,
120
149
        LAST_SIGNAL
121
150
};
122
151
 
124
153
 
125
154
static GtkActionEntry rb_removable_media_manager_actions [] =
126
155
{
127
 
        { "RemovableSourceEject", NULL, N_("_Eject"), NULL,
 
156
        { "RemovableSourceEject", GNOME_MEDIA_EJECT, N_("_Eject"), NULL,
128
157
          N_("Eject this medium"),
129
158
          G_CALLBACK (rb_removable_media_manager_cmd_eject_medium) },
 
159
        { "RemovableSourceCopyAllTracks", GTK_STOCK_CDROM, N_("_Copy to library"), NULL,
 
160
          N_("Copy all tracks to the library"),
 
161
          G_CALLBACK (rb_removable_media_manager_cmd_copy_tracks) },
130
162
        { "MusicScanMedia", NULL, N_("_Scan Removable Media"), NULL,
131
163
          N_("Scan for new Removable Media"),
132
164
          G_CALLBACK (rb_removable_media_manager_cmd_scan_media) },
140
172
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
141
173
 
142
174
        object_class->dispose = rb_removable_media_manager_dispose;
143
 
 
 
175
        object_class->finalize = rb_removable_media_manager_finalize;
144
176
        object_class->set_property = rb_removable_media_manager_set_property;
145
177
        object_class->get_property = rb_removable_media_manager_get_property;
146
178
 
166
198
                                                              "RBSourceList",
167
199
                                                              RB_TYPE_SOURCELIST,
168
200
                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
201
        g_object_class_install_property (object_class,
 
202
                                         PROP_SCANNED,
 
203
                                         g_param_spec_boolean ("scanned",
 
204
                                                               "scanned",
 
205
                                                               "Whether a scan has been performed",
 
206
                                                               FALSE,
 
207
                                                               G_PARAM_READABLE));
169
208
 
170
209
        rb_removable_media_manager_signals[MEDIUM_ADDED] =
171
210
                g_signal_new ("medium_added",
177
216
                              G_TYPE_NONE,
178
217
                              1, G_TYPE_OBJECT);
179
218
 
 
219
        rb_removable_media_manager_signals[TRANSFER_PROGRESS] =
 
220
                g_signal_new ("transfer-progress",
 
221
                              RB_TYPE_REMOVABLE_MEDIA_MANAGER,
 
222
                              G_SIGNAL_RUN_LAST,
 
223
                              G_STRUCT_OFFSET (RBRemovableMediaManagerClass, transfer_progress),
 
224
                              NULL, NULL,
 
225
                              rb_marshal_VOID__INT_INT_DOUBLE,
 
226
                              G_TYPE_NONE,
 
227
                              3, G_TYPE_INT, G_TYPE_INT, G_TYPE_DOUBLE);
 
228
        
 
229
        rb_removable_media_manager_signals[CREATE_SOURCE] =
 
230
                g_signal_new ("create-source",
 
231
                              RB_TYPE_REMOVABLE_MEDIA_MANAGER,
 
232
                              G_SIGNAL_RUN_LAST,
 
233
                              G_STRUCT_OFFSET (RBRemovableMediaManagerClass, create_source),
 
234
                              rb_signal_accumulator_object_handled, NULL,
 
235
                              rb_marshal_OBJECT__OBJECT,
 
236
                              RB_TYPE_SOURCE,
 
237
                              1, GNOME_VFS_TYPE_VOLUME);
 
238
 
180
239
        g_type_class_add_private (klass, sizeof (RBRemovableMediaManagerPrivate));
181
240
}
182
241
 
186
245
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
187
246
 
188
247
        priv->volume_mapping = g_hash_table_new (NULL, NULL);
 
248
        priv->transfer_queue = g_async_queue_new ();
 
249
 
 
250
        g_idle_add ((GSourceFunc)rb_removable_media_manager_load_media, mgr);
189
251
}
190
252
 
191
253
static void
210
272
                g_list_free (priv->sources);
211
273
                priv->sources = NULL;
212
274
        }
213
 
        if (priv->volume_mapping) {
214
 
                g_hash_table_destroy (priv->volume_mapping);
215
 
                priv->volume_mapping = NULL;
216
 
        }
217
 
        if (priv->cd_drive_mapping) {
218
 
                g_hash_table_destroy (priv->cd_drive_mapping);
219
 
                priv->cd_drive_mapping = NULL;
220
 
        }
221
275
 
222
276
        priv->disposed = TRUE;
223
277
 
225
279
}
226
280
 
227
281
static void
 
282
rb_removable_media_manager_finalize (GObject *object)
 
283
{
 
284
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (object);
 
285
 
 
286
        g_hash_table_destroy (priv->volume_mapping);
 
287
#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 
288
        g_hash_table_destroy (priv->cd_drive_mapping);
 
289
#endif
 
290
        g_async_queue_unref (priv->transfer_queue);
 
291
        
 
292
        G_OBJECT_CLASS (rb_removable_media_manager_parent_class)->finalize (object);
 
293
}
 
294
 
 
295
static void
228
296
rb_removable_media_manager_set_property (GObject *object,
229
297
                                  guint prop_id,
230
298
                                  const GValue *value,
278
346
        case PROP_SOURCELIST:
279
347
                g_value_set_object (value, priv->sourcelist);
280
348
                break;
 
349
        case PROP_SCANNED:
 
350
                g_value_set_boolean (value, priv->scanned);
 
351
                break;
281
352
        default:
282
353
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
283
354
                break;
294
365
                             NULL);
295
366
}
296
367
 
 
368
#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 
369
typedef struct
 
370
{
 
371
        gboolean removed;
 
372
        gboolean tray_opened;
 
373
        RBRemovableMediaManager *manager;
 
374
        NautilusBurnDrive *drive;
 
375
} RbCdDriveInfo;
 
376
 
297
377
#ifdef HAVE_BURN_DRIVE_DOOR
298
378
static
299
379
gboolean poll_tray_opened (RbCdDriveInfo *info)
345
425
        info->drive = drive;
346
426
        info->tray_opened = nautilus_burn_drive_door_is_open (drive);
347
427
        info->manager = manager;
 
428
 
348
429
        g_hash_table_insert (priv->cd_drive_mapping, drive, info);
349
430
        g_timeout_add (1000, (GSourceFunc)poll_tray_opened, info);
350
 
        if (!nautilus_burn_drive_door_is_open (drive)) {
351
 
                volume = gnome_vfs_volume_monitor_get_volume_for_path (monitor, drive->device);
352
 
                if (volume)
 
431
 
 
432
        volume = gnome_vfs_volume_monitor_get_volume_for_path (monitor, drive->device);
 
433
 
 
434
        if (volume) {
 
435
                if (!nautilus_burn_drive_door_is_open (drive)) {
353
436
                        rb_removable_media_manager_mount_volume (manager, volume);
354
 
        }
355
 
#endif
356
 
}
357
 
 
358
 
gboolean
 
437
                } else {
 
438
                        /* it may have got ejected while we weren't monitoring */
 
439
                        rb_removable_media_manager_unmount_volume (manager, volume);
 
440
                }
 
441
        }
 
442
#endif
 
443
}
 
444
 
 
445
static NautilusBurnDrive *
 
446
get_nautilus_burn_drive_for_path (const char *path)
 
447
{
 
448
#ifdef HAVE_BURN_DRIVE_NEW_FROM_PATH
 
449
        return nautilus_burn_drive_new_from_path (path);
 
450
#else
 
451
        GList *drives, *l;
 
452
        NautilusBurnDrive *path_drive = NULL;
 
453
 
 
454
        drives = nautilus_burn_drive_get_list (FALSE, FALSE);
 
455
        for (l = drives; l != NULL; l = g_list_next (l)) {
 
456
                NautilusBurnDrive *drive = (NautilusBurnDrive*)l->data;
 
457
 
 
458
                if (path_drive == NULL && strcmp (drive->device, path) == 0) {
 
459
                        path_drive = drive;
 
460
                } else {
 
461
                        nautilus_burn_drive_unref (drive);
 
462
                }
 
463
        }
 
464
        g_list_free (drives);
 
465
 
 
466
        return path_drive;
 
467
#endif
 
468
}
 
469
#endif /* NAUTILUS_BURN < 2.15.3 */
 
470
 
 
471
static char *
 
472
split_drive_from_cdda_uri (const char *uri)
 
473
{
 
474
        gchar *copy, *temp, *split;
 
475
        int len;
 
476
 
 
477
        if (!g_str_has_prefix (uri, "cdda://"))
 
478
                return NULL;
 
479
 
 
480
        len = strlen ("cdda://");
 
481
        
 
482
        copy = g_strdup (uri);
 
483
        split = g_utf8_strrchr (copy + len, -1, ':');
 
484
 
 
485
        if (split == NULL) {
 
486
                /* invalid URI, it doesn't contain a ':' */
 
487
                g_free (copy);
 
488
                return NULL;
 
489
        }
 
490
 
 
491
        *split = 0;
 
492
        temp = g_strdup (copy + len);
 
493
        g_free (copy);
 
494
 
 
495
        return temp;
 
496
}
 
497
 
 
498
static void
 
499
rb_removable_media_manager_playing_uri_changed_cb (RBShellPlayer *player,
 
500
                                                   const char *uri,
 
501
                                                   RBRemovableMediaManager *manager)
 
502
{
 
503
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (manager);
 
504
        char *old_drive = NULL;
 
505
        char *new_drive = NULL;
 
506
 
 
507
        /* extract the drive paths */
 
508
        if (priv->playing_uri)
 
509
                old_drive = split_drive_from_cdda_uri (priv->playing_uri);
 
510
 
 
511
        if (uri)
 
512
                new_drive = split_drive_from_cdda_uri (uri);
 
513
 
 
514
#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 
515
        /* if the drive we're playing from has changed, adjust the polling */
 
516
        if (old_drive == NULL || new_drive == NULL || strcmp (old_drive, new_drive) != 0) {
 
517
                if (old_drive) {
 
518
                        NautilusBurnDrive *drive;
 
519
 
 
520
                        rb_debug ("restarting monitoring of drive %s after playing", old_drive);
 
521
                        drive = get_nautilus_burn_drive_for_path (old_drive);
 
522
                        begin_cd_drive_monitor (drive, manager);
 
523
                        nautilus_burn_drive_unref (drive);
 
524
                }
 
525
                
 
526
                if (new_drive) {
 
527
                        NautilusBurnDrive *drive;
 
528
 
 
529
                        rb_debug ("stopping monitoring of drive %s while playing", new_drive);
 
530
                        drive = get_nautilus_burn_drive_for_path (new_drive);
 
531
                        /* removing it from the hash table makes it stop monitoring */
 
532
                        g_hash_table_remove (priv->cd_drive_mapping, drive);
 
533
                        nautilus_burn_drive_unref (drive);
 
534
                }
 
535
        }
 
536
#endif
 
537
 
 
538
        g_free (priv->playing_uri);
 
539
        priv->playing_uri = (uri) ? g_strdup (uri) : NULL;
 
540
}
 
541
 
 
542
        
 
543
static gboolean
359
544
rb_removable_media_manager_load_media (RBRemovableMediaManager *manager)
360
545
{
361
546
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (manager);
362
547
        GnomeVFSVolumeMonitor *monitor = gnome_vfs_get_volume_monitor ();
 
548
#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3)
363
549
        GList *drives;
 
550
#endif
 
551
        GObject *shell_player;
364
552
 
365
553
        /*
366
554
         * Monitor new (un)mounted file systems to look for new media
386
574
         * This needs to be done seperately from the above, because non-HAL systems don't
387
575
         * (currently) report audio cd insertions as mount events.
388
576
         */
 
577
#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3)
389
578
        priv->cd_drive_mapping = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)end_cd_drive_monitor);
390
579
        drives = nautilus_burn_drive_get_list (FALSE, FALSE);
391
580
        g_list_foreach (drives, (GFunc)begin_cd_drive_monitor, manager);
392
581
        g_list_free (drives);
 
582
#endif
393
583
 
394
 
        /* scan for media */
395
 
        rb_removable_media_manager_scan (manager);
 
584
        /* monitor the playing song, to disable cd drive polling */
 
585
        shell_player = rb_shell_get_player (priv->shell);
 
586
        g_signal_connect (shell_player, "playing-uri-changed",
 
587
                          G_CALLBACK (rb_removable_media_manager_playing_uri_changed_cb),
 
588
                          manager);
396
589
 
397
590
        return FALSE;
398
591
}
408
601
}
409
602
 
410
603
 
 
604
static gboolean 
 
605
remove_volume_by_source (GnomeVFSVolume *volume, RBSource *source, 
 
606
                         RBSource *ref_source)
 
607
{
 
608
        return (ref_source == source);
 
609
}
 
610
 
 
611
static void
 
612
rb_removable_media_manager_source_deleted_cb (RBSource *source, RBRemovableMediaManager *mgr)
 
613
{
 
614
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
 
615
 
 
616
        rb_debug ("removing source %p", source);
 
617
        g_hash_table_foreach_remove (priv->volume_mapping, 
 
618
                                     (GHRFunc)remove_volume_by_source,
 
619
                                     source);
 
620
        priv->sources = g_list_remove (priv->sources, source);
 
621
}
 
622
 
411
623
static void
412
624
rb_removable_media_manager_volume_unmounted_cb (GnomeVFSVolumeMonitor *monitor,
413
625
                             GnomeVFSVolume *volume, 
419
631
        rb_removable_media_manager_unmount_volume (mgr, volume);
420
632
}
421
633
 
422
 
 
423
634
static void
424
635
rb_removable_media_manager_mount_volume (RBRemovableMediaManager *mgr, GnomeVFSVolume *volume)
425
636
{
426
637
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
427
638
        RBRemovableMediaSource *source = NULL;
428
 
        RBShell *shell;
429
639
        char *fs_type, *device_path, *display_name, *hal_udi, *icon_name;
430
640
        GnomeVFSDeviceType device_type;
431
641
 
445
655
            device_type == GNOME_VFS_DEVICE_TYPE_NETWORK)
446
656
                return;
447
657
 
448
 
        g_object_get (G_OBJECT (mgr), "shell", &shell, NULL);
449
 
 
450
658
        fs_type = gnome_vfs_volume_get_filesystem_type (volume);
451
659
        device_path = gnome_vfs_volume_get_device_path (volume);
452
660
        display_name = gnome_vfs_volume_get_display_name (volume);
453
661
        hal_udi = gnome_vfs_volume_get_hal_udi (volume);
454
662
        icon_name = gnome_vfs_volume_get_icon (volume);
455
 
        rb_debug ("detecting new media - device_type=%d", device_type);
456
 
        rb_debug ("detecting new media - volumd_type=%d", gnome_vfs_volume_get_volume_type (volume));
 
663
        rb_debug ("detecting new media - device type=%d", device_type);
 
664
        rb_debug ("detecting new media - volume type=%d", gnome_vfs_volume_get_volume_type (volume));
457
665
        rb_debug ("detecting new media - fs type=%s", fs_type);
458
666
        rb_debug ("detecting new media - device path=%s", device_path);
459
667
        rb_debug ("detecting new media - display name=%s", display_name);
466
674
         * When volume is of the appropriate type, it creates a new source
467
675
         * to handle this volume
468
676
         */
 
677
 
 
678
        g_signal_emit (G_OBJECT (mgr), rb_removable_media_manager_signals[CREATE_SOURCE], 0,
 
679
                       volume, &source);
 
680
 
469
681
        if (source == NULL && rb_audiocd_is_volume_audiocd (volume))
470
 
                source = rb_audiocd_source_new (shell, volume);
471
 
#ifdef WITH_IPOD_SUPPORT
472
 
        if (source == NULL && rb_ipod_is_volume_ipod (volume))
473
 
                source = rb_ipod_source_new (shell, volume);
474
 
#endif
475
 
        if (source == NULL && rb_generic_player_is_volume_player (volume))
476
 
                source = rb_generic_player_source_new (shell, volume);
 
682
                source = rb_audiocd_source_new (priv->shell, volume);
477
683
 
478
684
        if (source) {
479
685
                g_hash_table_insert (priv->volume_mapping, volume, source);
480
686
                rb_removable_media_manager_append_media_source (mgr, source);
481
 
        } else
482
 
                rb_debug ("Unhanded media");
 
687
        } else {
 
688
                rb_debug ("Unhandled media");
 
689
        }
483
690
 
484
691
        g_free (fs_type);
485
692
        g_free (device_path);
486
693
        g_free (display_name);
487
694
        g_free (hal_udi);
488
695
        g_free (icon_name);
489
 
        g_object_unref (G_OBJECT (shell));
490
696
}
491
697
 
492
698
static void
501
707
        source = g_hash_table_lookup (priv->volume_mapping, volume);
502
708
        if (source) {
503
709
                rb_source_delete_thyself (RB_SOURCE (source));
504
 
                g_hash_table_remove (priv->volume_mapping, volume);
505
710
        }
506
711
}
507
712
 
508
 
static void
509
 
rb_removable_media_manager_source_deleted_cb (RBSource *source, RBRemovableMediaManager *mgr)
510
 
{
511
 
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
512
 
 
513
 
        rb_debug ("removing source %p", source);
514
 
        priv->sources = g_list_remove (priv->sources, source);
515
 
}
516
713
 
517
714
static void
518
715
rb_removable_media_manager_append_media_source (RBRemovableMediaManager *mgr, RBRemovableMediaSource *source)
522
719
        priv->sources = g_list_prepend (priv->sources, source);
523
720
        g_signal_connect_object (G_OBJECT (source), "deleted",
524
721
                                 G_CALLBACK (rb_removable_media_manager_source_deleted_cb), mgr, 0);
 
722
 
525
723
        g_signal_emit (G_OBJECT (mgr), rb_removable_media_manager_signals[MEDIUM_ADDED], 0,
526
724
                       source);
527
725
}
553
751
                                              mgr);
554
752
        }
555
753
 
 
754
#ifndef ENABLE_TRACK_TRANSFER
 
755
        {
 
756
                GtkAction *action;
 
757
 
 
758
                action = gtk_action_group_get_action (priv->actiongroup, "RemovableSourceCopyAllTracks");
 
759
                gtk_action_set_visible (action, FALSE);
 
760
        }
 
761
#endif
 
762
 
556
763
        gtk_ui_manager_insert_action_group (priv->uimanager,
557
764
                                            priv->actiongroup,
558
765
                                            0);
567
774
        if (succeeded)
568
775
                return;
569
776
 
570
 
        rb_error_dialog (NULL, error, detailed_error);
 
777
        rb_error_dialog (NULL, error, "%s", detailed_error);
571
778
}
572
779
 
573
780
static void
612
819
        rb_removable_media_manager_unmount_volume (manager, volume);
613
820
}
614
821
 
615
 
static void
 
822
#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 
823
static const char *
 
824
nautilus_burn_drive_get_device (NautilusBurnDrive *drive)
 
825
{
 
826
        g_return_val_if_fail (drive != NULL, NULL);
 
827
 
 
828
        return drive->device;
 
829
}
 
830
#endif
 
831
 
 
832
void
616
833
rb_removable_media_manager_scan (RBRemovableMediaManager *manager)
617
834
{
618
835
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (manager);
620
837
        GList *list, *it;
621
838
        GnomeVFSVolume *volume;
622
839
        struct VolumeCheckData check_data;
 
840
 
 
841
        priv->scanned = TRUE;
623
842
                
624
843
        list = gnome_vfs_volume_monitor_get_mounted_volumes (monitor);
625
844
        
644
863
        g_list_free (list);
645
864
 
646
865
        /* scan cd drives */
 
866
#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 
867
        list = nautilus_burn_drive_monitor_get_drives (nautilus_burn_get_drive_monitor ());
 
868
#else
647
869
        list = nautilus_burn_drive_get_list (FALSE, FALSE);
 
870
#endif
648
871
        for  (it = list; it != NULL; it = g_list_next (it)) {
649
 
                NautilusBurnDrive *drive = (NautilusBurnDrive*)it->data;
650
 
                volume = gnome_vfs_volume_monitor_get_volume_for_path (monitor, drive->device);
 
872
                NautilusBurnDrive *drive = (NautilusBurnDrive *)it->data;
 
873
 
 
874
                volume = gnome_vfs_volume_monitor_get_volume_for_path (monitor, nautilus_burn_drive_get_device (drive));
651
875
                if (volume) {
652
876
                        rb_removable_media_manager_mount_volume (manager, volume);
653
877
                        gnome_vfs_volume_unref (volume);
655
879
        }
656
880
        g_list_free (list);
657
881
}
 
882
 
 
883
 
 
884
#ifdef ENABLE_TRACK_TRANSFER
 
885
/* Track transfer */
 
886
 
 
887
typedef struct {
 
888
        RBRemovableMediaManager *manager;
 
889
        RhythmDBEntry *entry;
 
890
        char *dest;
 
891
        char *mime_type;
 
892
        gboolean failed;
 
893
        RBTranferCompleteCallback callback;
 
894
        gpointer userdata;
 
895
} TransferData;
 
896
 
 
897
static void
 
898
emit_progress (RBRemovableMediaManager *mgr)
 
899
{
 
900
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
 
901
 
 
902
        g_signal_emit (G_OBJECT (mgr), rb_removable_media_manager_signals[TRANSFER_PROGRESS], 0,
 
903
                       priv->transfer_done,
 
904
                       priv->transfer_total,
 
905
                       priv->transfer_fraction);
 
906
}
 
907
 
 
908
static void
 
909
error_cb (RBEncoder *encoder, GError *error, TransferData *data)
 
910
{
 
911
        rb_debug ("Error transferring track to %s: %s", data->dest, error->message);
 
912
        rb_error_dialog (NULL, _("Error transferring track"), "%s", error->message);
 
913
 
 
914
        data->failed = TRUE;
 
915
        rb_encoder_cancel (encoder);
 
916
}
 
917
 
 
918
static void
 
919
progress_cb (RBEncoder *encoder, double fraction, TransferData *data)
 
920
{
 
921
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (data->manager);
 
922
 
 
923
        rb_debug ("transfer progress %f", (float)fraction);
 
924
        priv->transfer_fraction = fraction;
 
925
        emit_progress (data->manager);
 
926
}
 
927
 
 
928
static void
 
929
completed_cb (RBEncoder *encoder, TransferData *data)
 
930
{
 
931
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (data->manager);
 
932
 
 
933
        rb_debug ("completed transferring track to %s", data->dest);
 
934
        if (!data->failed)
 
935
                (data->callback) (data->entry, data->dest, data->userdata);
 
936
 
 
937
        priv->transfer_running = FALSE;
 
938
        priv->transfer_done++;
 
939
        priv->transfer_fraction = 0.0;
 
940
        do_transfer (data->manager);
 
941
 
 
942
        g_object_unref (G_OBJECT (encoder));
 
943
        g_free (data->dest);
 
944
        g_free (data->mime_type);
 
945
        g_free (data);
 
946
}
 
947
 
 
948
static void
 
949
do_transfer (RBRemovableMediaManager *manager)
 
950
{
 
951
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (manager);
 
952
        TransferData *data;
 
953
        RBEncoder *encoder;
 
954
 
 
955
        g_assert (rb_is_main_thread ());
 
956
        
 
957
        emit_progress (manager);
 
958
 
 
959
        if (priv->transfer_running)
 
960
                return;
 
961
 
 
962
        data = g_async_queue_try_pop (priv->transfer_queue);
 
963
        if (data == NULL) {
 
964
                priv->transfer_total = 0;
 
965
                priv->transfer_done = 0;
 
966
                emit_progress (manager);
 
967
                return;
 
968
        }
 
969
 
 
970
        priv->transfer_running = TRUE;
 
971
        priv->transfer_fraction = 0.0;
 
972
 
 
973
        encoder = rb_encoder_new ();
 
974
        g_signal_connect (G_OBJECT (encoder),
 
975
                          "error", G_CALLBACK (error_cb),
 
976
                          data);
 
977
        g_signal_connect (G_OBJECT (encoder),
 
978
                          "progress", G_CALLBACK (progress_cb),
 
979
                          data);
 
980
        g_signal_connect (G_OBJECT (encoder),
 
981
                          "completed", G_CALLBACK (completed_cb),
 
982
                          data);
 
983
        rb_encoder_encode (encoder, data->entry, data->dest, NULL);
 
984
}
 
985
 
 
986
void
 
987
rb_removable_media_manager_queue_transfer (RBRemovableMediaManager *manager,
 
988
                                          RhythmDBEntry *entry,
 
989
                                          const char *dest,
 
990
                                          const char *mime_type,
 
991
                                          RBTranferCompleteCallback callback,
 
992
                                          gpointer userdata)
 
993
{
 
994
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (manager);
 
995
        TransferData *data;
 
996
 
 
997
        g_assert (rb_is_main_thread ());
 
998
 
 
999
        data = g_new0 (TransferData, 1);
 
1000
        data->manager = manager;
 
1001
        data->entry = entry;
 
1002
        data->dest = g_strdup (dest);
 
1003
        data->mime_type = g_strdup (mime_type);
 
1004
        data->callback = callback;
 
1005
        data->userdata = userdata;
 
1006
 
 
1007
        g_async_queue_push (priv->transfer_queue, data);
 
1008
        priv->transfer_total++;
 
1009
        do_transfer (manager);
 
1010
}
 
1011
 
 
1012
static gboolean
 
1013
copy_entry (RhythmDBQueryModel *model,
 
1014
            GtkTreePath *path,
 
1015
            GtkTreeIter *iter,
 
1016
            GList **list)
 
1017
{
 
1018
        GList *l;
 
1019
        l = g_list_append (*list, rhythmdb_query_model_iter_to_entry (model, iter));
 
1020
        *list = l;
 
1021
        return FALSE;
 
1022
}
 
1023
#endif
 
1024
 
 
1025
static void
 
1026
rb_removable_media_manager_cmd_copy_tracks (GtkAction *action, RBRemovableMediaManager *mgr)
 
1027
{
 
1028
#ifdef ENABLE_TRACK_TRANSFER
 
1029
        RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
 
1030
        RBRemovableMediaSource *source;
 
1031
        RBLibrarySource *library;
 
1032
        RhythmDBQueryModel *model;
 
1033
        GList *list = NULL;
 
1034
 
 
1035
        source = RB_REMOVABLE_MEDIA_SOURCE (priv->selected_source);
 
1036
        g_object_get (G_OBJECT (source), "query-model", &model, NULL);
 
1037
        g_object_get (G_OBJECT (priv->shell), "library-source", &library, NULL);
 
1038
 
 
1039
        gtk_tree_model_foreach (GTK_TREE_MODEL (model), (GtkTreeModelForeachFunc)copy_entry, &list);
 
1040
        rb_source_paste (RB_SOURCE (library), list);
 
1041
        g_list_free (list);
 
1042
 
 
1043
        g_object_unref (G_OBJECT (model));
 
1044
        g_object_unref (G_OBJECT (library));
 
1045
#endif
 
1046
}
 
1047