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.
26
#include <glib/gi18n.h>
24
27
#include <gtk/gtk.h>
25
#include <libgnome/gnome-i18n.h>
26
29
#include <libgnomevfs/gnome-vfs.h>
27
31
#include <nautilus-burn-drive.h>
32
#ifndef NAUTILUS_BURN_CHECK_VERSION
33
#define NAUTILUS_BURN_CHECK_VERSION(a,b,c) FALSE
36
#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
37
#include <nautilus-burn.h>
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"
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"
55
#ifdef ENABLE_TRACK_TRANSFER
56
#include "rb-encoder.h"
43
59
#ifndef HAVE_BURN_DRIVE_UNREF
44
60
#define nautilus_burn_drive_unref nautilus_burn_drive_free
125
154
static GtkActionEntry rb_removable_media_manager_actions [] =
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) },
178
217
1, G_TYPE_OBJECT);
219
rb_removable_media_manager_signals[TRANSFER_PROGRESS] =
220
g_signal_new ("transfer-progress",
221
RB_TYPE_REMOVABLE_MEDIA_MANAGER,
223
G_STRUCT_OFFSET (RBRemovableMediaManagerClass, transfer_progress),
225
rb_marshal_VOID__INT_INT_DOUBLE,
227
3, G_TYPE_INT, G_TYPE_INT, G_TYPE_DOUBLE);
229
rb_removable_media_manager_signals[CREATE_SOURCE] =
230
g_signal_new ("create-source",
231
RB_TYPE_REMOVABLE_MEDIA_MANAGER,
233
G_STRUCT_OFFSET (RBRemovableMediaManagerClass, create_source),
234
rb_signal_accumulator_object_handled, NULL,
235
rb_marshal_OBJECT__OBJECT,
237
1, GNOME_VFS_TYPE_VOLUME);
180
239
g_type_class_add_private (klass, sizeof (RBRemovableMediaManagerPrivate));
345
425
info->drive = drive;
346
426
info->tray_opened = nautilus_burn_drive_door_is_open (drive);
347
427
info->manager = manager;
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);
432
volume = gnome_vfs_volume_monitor_get_volume_for_path (monitor, drive->device);
435
if (!nautilus_burn_drive_door_is_open (drive)) {
353
436
rb_removable_media_manager_mount_volume (manager, volume);
438
/* it may have got ejected while we weren't monitoring */
439
rb_removable_media_manager_unmount_volume (manager, volume);
445
static NautilusBurnDrive *
446
get_nautilus_burn_drive_for_path (const char *path)
448
#ifdef HAVE_BURN_DRIVE_NEW_FROM_PATH
449
return nautilus_burn_drive_new_from_path (path);
452
NautilusBurnDrive *path_drive = NULL;
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;
458
if (path_drive == NULL && strcmp (drive->device, path) == 0) {
461
nautilus_burn_drive_unref (drive);
464
g_list_free (drives);
469
#endif /* NAUTILUS_BURN < 2.15.3 */
472
split_drive_from_cdda_uri (const char *uri)
474
gchar *copy, *temp, *split;
477
if (!g_str_has_prefix (uri, "cdda://"))
480
len = strlen ("cdda://");
482
copy = g_strdup (uri);
483
split = g_utf8_strrchr (copy + len, -1, ':');
486
/* invalid URI, it doesn't contain a ':' */
492
temp = g_strdup (copy + len);
499
rb_removable_media_manager_playing_uri_changed_cb (RBShellPlayer *player,
501
RBRemovableMediaManager *manager)
503
RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (manager);
504
char *old_drive = NULL;
505
char *new_drive = NULL;
507
/* extract the drive paths */
508
if (priv->playing_uri)
509
old_drive = split_drive_from_cdda_uri (priv->playing_uri);
512
new_drive = split_drive_from_cdda_uri (uri);
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) {
518
NautilusBurnDrive *drive;
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);
527
NautilusBurnDrive *drive;
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);
538
g_free (priv->playing_uri);
539
priv->playing_uri = (uri) ? g_strdup (uri) : NULL;
359
544
rb_removable_media_manager_load_media (RBRemovableMediaManager *manager)
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)
551
GObject *shell_player;
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.
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);
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),
445
655
device_type == GNOME_VFS_DEVICE_TYPE_NETWORK)
448
g_object_get (G_OBJECT (mgr), "shell", &shell, NULL);
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
678
g_signal_emit (G_OBJECT (mgr), rb_removable_media_manager_signals[CREATE_SOURCE], 0,
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);
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);
479
685
g_hash_table_insert (priv->volume_mapping, volume, source);
480
686
rb_removable_media_manager_append_media_source (mgr, source);
482
rb_debug ("Unhanded media");
688
rb_debug ("Unhandled media");
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));
656
880
g_list_free (list);
884
#ifdef ENABLE_TRACK_TRANSFER
888
RBRemovableMediaManager *manager;
889
RhythmDBEntry *entry;
893
RBTranferCompleteCallback callback;
898
emit_progress (RBRemovableMediaManager *mgr)
900
RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
902
g_signal_emit (G_OBJECT (mgr), rb_removable_media_manager_signals[TRANSFER_PROGRESS], 0,
904
priv->transfer_total,
905
priv->transfer_fraction);
909
error_cb (RBEncoder *encoder, GError *error, TransferData *data)
911
rb_debug ("Error transferring track to %s: %s", data->dest, error->message);
912
rb_error_dialog (NULL, _("Error transferring track"), "%s", error->message);
915
rb_encoder_cancel (encoder);
919
progress_cb (RBEncoder *encoder, double fraction, TransferData *data)
921
RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (data->manager);
923
rb_debug ("transfer progress %f", (float)fraction);
924
priv->transfer_fraction = fraction;
925
emit_progress (data->manager);
929
completed_cb (RBEncoder *encoder, TransferData *data)
931
RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (data->manager);
933
rb_debug ("completed transferring track to %s", data->dest);
935
(data->callback) (data->entry, data->dest, data->userdata);
937
priv->transfer_running = FALSE;
938
priv->transfer_done++;
939
priv->transfer_fraction = 0.0;
940
do_transfer (data->manager);
942
g_object_unref (G_OBJECT (encoder));
944
g_free (data->mime_type);
949
do_transfer (RBRemovableMediaManager *manager)
951
RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (manager);
955
g_assert (rb_is_main_thread ());
957
emit_progress (manager);
959
if (priv->transfer_running)
962
data = g_async_queue_try_pop (priv->transfer_queue);
964
priv->transfer_total = 0;
965
priv->transfer_done = 0;
966
emit_progress (manager);
970
priv->transfer_running = TRUE;
971
priv->transfer_fraction = 0.0;
973
encoder = rb_encoder_new ();
974
g_signal_connect (G_OBJECT (encoder),
975
"error", G_CALLBACK (error_cb),
977
g_signal_connect (G_OBJECT (encoder),
978
"progress", G_CALLBACK (progress_cb),
980
g_signal_connect (G_OBJECT (encoder),
981
"completed", G_CALLBACK (completed_cb),
983
rb_encoder_encode (encoder, data->entry, data->dest, NULL);
987
rb_removable_media_manager_queue_transfer (RBRemovableMediaManager *manager,
988
RhythmDBEntry *entry,
990
const char *mime_type,
991
RBTranferCompleteCallback callback,
994
RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (manager);
997
g_assert (rb_is_main_thread ());
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;
1007
g_async_queue_push (priv->transfer_queue, data);
1008
priv->transfer_total++;
1009
do_transfer (manager);
1013
copy_entry (RhythmDBQueryModel *model,
1019
l = g_list_append (*list, rhythmdb_query_model_iter_to_entry (model, iter));
1026
rb_removable_media_manager_cmd_copy_tracks (GtkAction *action, RBRemovableMediaManager *mgr)
1028
#ifdef ENABLE_TRACK_TRANSFER
1029
RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
1030
RBRemovableMediaSource *source;
1031
RBLibrarySource *library;
1032
RhythmDBQueryModel *model;
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);
1039
gtk_tree_model_foreach (GTK_TREE_MODEL (model), (GtkTreeModelForeachFunc)copy_entry, &list);
1040
rb_source_paste (RB_SOURCE (library), list);
1043
g_object_unref (G_OBJECT (model));
1044
g_object_unref (G_OBJECT (library));