~ubuntu-branches/ubuntu/oneiric/rhythmbox/oneiric

« back to all changes in this revision

Viewing changes to shell/rb-shell-clipboard.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2006-06-26 19:06:10 UTC
  • mto: (2.1.1 lenny) (1.1.37 upstream)
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20060626190610-08x8lgvvfs0gr619
Tags: upstream-0.9.5
ImportĀ upstreamĀ versionĀ 0.9.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *
18
18
 *  You should have received a copy of the GNU General Public License
19
19
 *  along with this program; if not, write to the Free Software
20
 
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
20
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
21
21
 *
22
22
 */
23
23
 
25
25
 
26
26
#include <glib/gi18n.h>
27
27
#include <gtk/gtk.h>
 
28
#include <gtk/gtkstock.h>
28
29
 
29
30
#include "rb-shell-clipboard.h"
 
31
#include "rb-playlist-manager.h"
 
32
#include "rb-play-queue-source.h"
 
33
#include "rb-sourcelist-model.h"
30
34
#include "rhythmdb.h"
31
35
#include "rb-debug.h"
32
 
#include "rb-static-playlist-source.h"
33
 
#include "rb-play-queue-source.h"
34
 
#include <gtk/gtkstock.h>
35
36
 
36
37
static void rb_shell_clipboard_class_init (RBShellClipboardClass *klass);
37
38
static void rb_shell_clipboard_init (RBShellClipboard *shell_clipboard);
46
47
                                             guint prop_id,
47
48
                                             GValue *value,
48
49
                                             GParamSpec *pspec);
49
 
static void rb_shell_clipboard_sync (RBShellClipboard *clipboard);
 
50
static gboolean rb_shell_clipboard_sync (RBShellClipboard *clipboard);
50
51
static void rb_shell_clipboard_cmd_select_all (GtkAction *action,
51
52
                                               RBShellClipboard *clipboard);
52
53
static void rb_shell_clipboard_cmd_select_none (GtkAction *action,
66
67
static void rb_shell_clipboard_set (RBShellClipboard *clipboard,
67
68
                                    GList *nodes);
68
69
static gboolean rb_shell_clipboard_idle_poll_deletions (RBShellClipboard *clipboard);
 
70
static void rb_shell_clipboard_playlist_added_cb (RBPlaylistManager *mgr,
 
71
                                                  RBPlaylistSource *source,
 
72
                                                  RBShellClipboard *clipboard);
69
73
static void rb_shell_clipboard_entry_deleted_cb (RhythmDB *db,
70
74
                                                 RhythmDBEntry *entry,
71
75
                                                 RBShellClipboard *clipboard);
72
76
static void rb_shell_clipboard_entryview_changed_cb (RBEntryView *view,
73
77
                                                     RBShellClipboard *clipboard);
 
78
static void rb_shell_clipboard_entries_changed_cb (RBEntryView *view,
 
79
                                                   gpointer stuff,
 
80
                                                   RBShellClipboard *clipboard);
 
81
static void rb_shell_clipboard_cmd_add_to_playlist_new (GtkAction *action,
 
82
                                                        RBShellClipboard *clipboard);
74
83
static void rb_shell_clipboard_cmd_add_song_to_queue (GtkAction *action,
75
84
                                                      RBShellClipboard *clipboard);
76
85
static void rb_shell_clipboard_cmd_song_info (GtkAction *action,
77
86
                                              RBShellClipboard *clipboard);
78
87
static void rb_shell_clipboard_cmd_queue_song_info (GtkAction *action,
79
88
                                                    RBShellClipboard *clipboard);
 
89
static gboolean rebuild_playlist_menu (RBShellClipboard *clipboard);
80
90
 
81
91
struct RBShellClipboardPrivate
82
92
{
83
93
        RhythmDB *db;
84
94
        RBSource *source;
85
95
        RBStaticPlaylistSource *queue_source;
 
96
        RBPlaylistManager *playlist_manager;
86
97
 
 
98
        GtkUIManager *ui_mgr;
87
99
        GtkActionGroup *actiongroup;
 
100
        guint playlist_menu_ui_id;
88
101
 
89
102
        GHashTable *signal_hash;
90
103
 
91
104
        GAsyncQueue *deleted_queue;
92
105
 
93
 
        guint idle_sync_id;
 
106
        guint idle_deletion_id, idle_sync_id, idle_playlist_id;
94
107
 
95
108
        GList *entries;
96
109
};
104
117
        PROP_ACTION_GROUP,
105
118
        PROP_DB,
106
119
        PROP_QUEUE_SOURCE,
 
120
        PROP_PLAYLIST_MANAGER,
 
121
        PROP_UI_MANAGER,
107
122
};
108
123
 
109
124
static GtkActionEntry rb_shell_clipboard_actions [] =
126
141
        { "EditDelete", GTK_STOCK_REMOVE, N_("_Remove"), NULL,
127
142
          N_("Remove selection"),
128
143
          G_CALLBACK (rb_shell_clipboard_cmd_delete) },
129
 
        { "EditMovetoTrash", GTK_STOCK_DELETE, N_("_Move To Trash"), "<control>T",
 
144
        { "EditMovetoTrash", GTK_STOCK_DELETE, N_("_Move to Trash"), "<control>T",
130
145
          N_("Move selection to the trash"),
131
146
          G_CALLBACK (rb_shell_clipboard_cmd_move_to_trash) },
132
147
 
133
 
        { "AddToQueue", GTK_STOCK_ADD, N_("Add _to Play Queue"), "<control>T",
 
148
        { "EditPlaylistAdd", NULL, N_("Add to P_laylist") },
 
149
        { "EditPlaylistAddNew", GTK_STOCK_ADD, N_("_New Playlist..."), NULL,
 
150
          N_("Add the selected songs to a new playlist"),
 
151
          G_CALLBACK (rb_shell_clipboard_cmd_add_to_playlist_new) },
 
152
        { "AddToQueue", GTK_STOCK_ADD, N_("Add _to Play Queue"), NULL,
134
153
          N_("Add the selected songs to the play queue"),
135
154
          G_CALLBACK (rb_shell_clipboard_cmd_add_song_to_queue) },
136
155
        { "QueueDelete", GTK_STOCK_REMOVE, N_("Remove"), NULL,
146
165
};
147
166
static guint rb_shell_clipboard_n_actions = G_N_ELEMENTS (rb_shell_clipboard_actions);
148
167
 
 
168
static const char *playlist_menu_paths[] = {
 
169
        "/MenuBar/EditMenu/EditPlaylistAddMenu/EditPlaylistAddPlaceholder",
 
170
        "/BrowserSourceViewPopup/BrowserSourcePopupPlaylistAdd/BrowserSourcePopupPlaylistAddPlaceholder",
 
171
        "/PlaylistViewPopup/PlaylistPopupPlaylistAdd/PlaylistPopupPlaylistAddPlaceholder",
 
172
};
 
173
static guint num_playlist_menu_paths = G_N_ELEMENTS (playlist_menu_paths);
 
174
 
 
175
 
149
176
G_DEFINE_TYPE (RBShellClipboard, rb_shell_clipboard, G_TYPE_OBJECT)
150
177
 
151
178
static void
187
214
                                                              "RBPlaylistSource object",
188
215
                                                              RB_TYPE_PLAYLIST_SOURCE,
189
216
                                                              G_PARAM_READWRITE));
 
217
        g_object_class_install_property (object_class,
 
218
                                         PROP_PLAYLIST_MANAGER,
 
219
                                         g_param_spec_object ("playlist-manager",
 
220
                                                              "RBPlaylistManager",
 
221
                                                              "RBPlaylistManager object",
 
222
                                                              RB_TYPE_PLAYLIST_MANAGER,
 
223
                                                              G_PARAM_READWRITE));
 
224
        g_object_class_install_property (object_class,
 
225
                                         PROP_UI_MANAGER,
 
226
                                         g_param_spec_object ("ui-manager",
 
227
                                                              "GtkUIManager",
 
228
                                                              "GtkUIManager object",
 
229
                                                              GTK_TYPE_UI_MANAGER,
 
230
                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
190
231
 
191
232
        g_type_class_add_private (klass, sizeof (RBShellClipboardPrivate));
192
233
}
201
242
 
202
243
        shell_clipboard->priv->deleted_queue = g_async_queue_new ();
203
244
 
204
 
        shell_clipboard->priv->idle_sync_id = g_idle_add ((GSourceFunc) rb_shell_clipboard_idle_poll_deletions, shell_clipboard); 
 
245
        shell_clipboard->priv->idle_deletion_id = g_idle_add ((GSourceFunc) rb_shell_clipboard_idle_poll_deletions, shell_clipboard); 
205
246
}
206
247
 
207
248
static void
224
265
 
225
266
        if (shell_clipboard->priv->idle_sync_id)
226
267
                g_source_remove (shell_clipboard->priv->idle_sync_id);
 
268
        if (shell_clipboard->priv->idle_deletion_id)
 
269
                g_source_remove (shell_clipboard->priv->idle_deletion_id);
 
270
        if (shell_clipboard->priv->idle_playlist_id)
 
271
                g_source_remove (shell_clipboard->priv->idle_playlist_id);
227
272
        
228
273
        G_OBJECT_CLASS (rb_shell_clipboard_parent_class)->finalize (object);
229
274
}
252
297
}
253
298
 
254
299
static void
 
300
rb_shell_clipboard_set_source_internal (RBShellClipboard *clipboard,
 
301
                                        RBSource *source)
 
302
{
 
303
        if (clipboard->priv->source != NULL) {
 
304
                RBEntryView *songs = rb_source_get_entry_view (clipboard->priv->source);
 
305
 
 
306
                if (songs) {
 
307
                        g_signal_handlers_disconnect_by_func (G_OBJECT (songs),
 
308
                                                              G_CALLBACK (rb_shell_clipboard_entryview_changed_cb),
 
309
                                                              clipboard);
 
310
                        g_signal_handlers_disconnect_by_func (G_OBJECT (songs),
 
311
                                                              G_CALLBACK (rb_shell_clipboard_entries_changed_cb),
 
312
                                                              clipboard);
 
313
                }
 
314
        }
 
315
        clipboard->priv->source = source;
 
316
        rb_debug ("selected source %p", source);
 
317
 
 
318
        rb_shell_clipboard_sync (clipboard);
 
319
 
 
320
        if (clipboard->priv->source != NULL) {
 
321
                RBEntryView *songs = rb_source_get_entry_view (clipboard->priv->source);
 
322
 
 
323
                if (songs) {
 
324
                        g_signal_connect_object (G_OBJECT (songs),
 
325
                                                 "selection-changed",
 
326
                                                 G_CALLBACK (rb_shell_clipboard_entryview_changed_cb),
 
327
                                                 clipboard, 0);
 
328
                        g_signal_connect_object (G_OBJECT (songs),
 
329
                                                 "entry-added",
 
330
                                                 G_CALLBACK (rb_shell_clipboard_entries_changed_cb),
 
331
                                                 clipboard, 0);
 
332
                        g_signal_connect_object (G_OBJECT (songs),
 
333
                                                 "entry-deleted",
 
334
                                                 G_CALLBACK (rb_shell_clipboard_entries_changed_cb),
 
335
                                                 clipboard, 0);
 
336
                        g_signal_connect_object (G_OBJECT (songs),
 
337
                                                 "entries-replaced",
 
338
                                                 G_CALLBACK (rb_shell_clipboard_entryview_changed_cb),
 
339
                                                 clipboard, 0);
 
340
                }
 
341
        }
 
342
}
 
343
 
 
344
static void
255
345
rb_shell_clipboard_set_property (GObject *object,
256
346
                                 guint prop_id,
257
347
                                 const GValue *value,
262
352
        switch (prop_id)
263
353
        {
264
354
        case PROP_SOURCE:
265
 
                if (clipboard->priv->source != NULL)
266
 
                {
267
 
                        RBEntryView *songs = rb_source_get_entry_view (clipboard->priv->source);
268
 
 
269
 
                        g_signal_handlers_disconnect_by_func (G_OBJECT (songs),
270
 
                                                              G_CALLBACK (rb_shell_clipboard_entryview_changed_cb),
271
 
                                                              clipboard);
272
 
                }
273
 
                clipboard->priv->source = g_value_get_object (value);
274
 
                rb_debug ("selected source %p", g_value_get_object (value));
275
 
 
276
 
                rb_shell_clipboard_sync (clipboard);
277
 
 
278
 
                if (clipboard->priv->source != NULL)
279
 
                {
280
 
                        RBEntryView *songs = rb_source_get_entry_view (clipboard->priv->source);
281
 
 
282
 
                        g_signal_connect_object (G_OBJECT (songs),
283
 
                                                 "selection-changed",
284
 
                                                 G_CALLBACK (rb_shell_clipboard_entryview_changed_cb),
285
 
                                                 clipboard, 0);
286
 
                }
 
355
                rb_shell_clipboard_set_source_internal (clipboard, g_value_get_object (value));
287
356
                break;
288
357
        case PROP_ACTION_GROUP:
289
358
                clipboard->priv->actiongroup = g_value_get_object (value);
295
364
        case PROP_DB:
296
365
                clipboard->priv->db = g_value_get_object (value);
297
366
                break;
 
367
        case PROP_UI_MANAGER:
 
368
                clipboard->priv->ui_mgr = g_value_get_object (value);
 
369
                break;
 
370
        case PROP_PLAYLIST_MANAGER:
 
371
                clipboard->priv->playlist_manager = g_value_get_object (value);
 
372
                if (clipboard->priv->playlist_manager) {
 
373
                        g_signal_connect_object (G_OBJECT (clipboard->priv->playlist_manager),
 
374
                                                 "playlist-added", G_CALLBACK (rb_shell_clipboard_playlist_added_cb),
 
375
                                                 clipboard, 0);
 
376
 
 
377
                        rebuild_playlist_menu (clipboard);
 
378
                }
 
379
 
 
380
                break;
298
381
        case PROP_QUEUE_SOURCE:
299
382
                clipboard->priv->queue_source = g_value_get_object (value);
300
383
                if (clipboard->priv->queue_source) {
331
414
        case PROP_DB:
332
415
                g_value_set_object (value, clipboard->priv->db);
333
416
                break;
 
417
        case PROP_UI_MANAGER:
 
418
                g_value_set_object (value, clipboard->priv->ui_mgr);
 
419
                break;
 
420
        case PROP_PLAYLIST_MANAGER:
 
421
                g_value_set_object (value, clipboard->priv->playlist_manager);
 
422
                break;
334
423
        case PROP_QUEUE_SOURCE:
335
424
                g_value_set_object (value, clipboard->priv->queue_source);
336
425
                break;
352
441
}
353
442
 
354
443
RBShellClipboard *
355
 
rb_shell_clipboard_new (GtkActionGroup *actiongroup, RhythmDB *db)
 
444
rb_shell_clipboard_new (GtkActionGroup *actiongroup,GtkUIManager *ui_mgr, RhythmDB *db)
356
445
{
357
446
        return g_object_new (RB_TYPE_SHELL_CLIPBOARD,
358
447
                             "action-group", actiongroup,
 
448
                             "ui-manager", ui_mgr,
359
449
                             "db", db,
360
450
                             NULL);
361
451
}
362
452
 
363
 
static void
 
453
static gboolean
364
454
rb_shell_clipboard_sync (RBShellClipboard *clipboard)
365
455
{
366
 
        gboolean have_selection;
 
456
        RBEntryView *view;
 
457
        gboolean have_selection = FALSE;
367
458
        gboolean have_sidebar_selection = FALSE;
368
459
        gboolean can_cut = FALSE;
369
460
        gboolean can_paste = FALSE;
371
462
        gboolean can_copy = FALSE;
372
463
        gboolean can_add_to_queue = FALSE;
373
464
        gboolean can_move_to_trash = FALSE;
 
465
        gboolean can_select_all = FALSE;
374
466
        GtkAction *action;
375
467
 
376
468
        if (!clipboard->priv->source)
377
 
                return;
378
 
 
379
 
        have_selection = rb_entry_view_have_selection (rb_source_get_entry_view (clipboard->priv->source));
 
469
                return FALSE;
 
470
 
 
471
        clipboard->priv->idle_sync_id = 0;
 
472
 
 
473
        view = rb_source_get_entry_view (clipboard->priv->source);
 
474
        if (view) {
 
475
                have_selection = rb_entry_view_have_selection (view);
 
476
                can_select_all = !rb_entry_view_have_complete_selection (view);
 
477
        }
 
478
 
380
479
        if (clipboard->priv->queue_source) {
381
480
                RBEntryView *sidebar;
382
481
                g_object_get (G_OBJECT (clipboard->priv->queue_source), "sidebar", &sidebar, NULL);
387
486
        rb_debug ("syncing clipboard");
388
487
        
389
488
        if (g_list_length (clipboard->priv->entries) > 0)
390
 
                can_paste = rb_source_can_cut (clipboard->priv->source);
 
489
                can_paste = rb_source_can_paste (clipboard->priv->source);
391
490
 
392
491
        if (have_selection) {
393
492
                can_cut = rb_source_can_cut (clipboard->priv->source);
394
493
                can_delete = rb_source_can_delete (clipboard->priv->source);
395
494
                can_copy = rb_source_can_copy (clipboard->priv->source);
396
495
                can_move_to_trash = rb_source_can_move_to_trash (clipboard->priv->source);
 
496
 
397
497
                if (clipboard->priv->queue_source)
398
498
                        can_add_to_queue = rb_source_can_add_to_queue (clipboard->priv->source);
399
499
        }
400
500
 
401
 
        action = gtk_action_group_get_action (clipboard->priv->actiongroup,
402
 
                                              "EditCut");
 
501
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, "EditCut");
403
502
        g_object_set (G_OBJECT (action), "sensitive", can_cut, NULL);
404
 
        action = gtk_action_group_get_action (clipboard->priv->actiongroup,
405
 
                                              "EditDelete");
 
503
        
 
504
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, "EditDelete");
406
505
        g_object_set (G_OBJECT (action), "sensitive", can_delete, NULL);
407
 
        action = gtk_action_group_get_action (clipboard->priv->actiongroup,
408
 
                                              "EditMovetoTrash");
 
506
        
 
507
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, "EditMovetoTrash");
409
508
        g_object_set (G_OBJECT (action), "sensitive", can_move_to_trash, NULL);
410
 
        action = gtk_action_group_get_action (clipboard->priv->actiongroup,
411
 
                                              "EditCopy");
 
509
        
 
510
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, "EditCopy");
412
511
        g_object_set (G_OBJECT (action), "sensitive", can_copy, NULL);
413
512
 
414
 
        action = gtk_action_group_get_action (clipboard->priv->actiongroup,
415
 
                                              "EditPaste");
 
513
        action = gtk_action_group_get_action (clipboard->priv->actiongroup,"EditPaste");
416
514
        g_object_set (G_OBJECT (action), "sensitive", can_paste, NULL);
417
515
 
418
 
        action = gtk_action_group_get_action (clipboard->priv->actiongroup,
419
 
                                              "AddToQueue");
 
516
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, "EditPlaylistAdd");
 
517
        g_object_set (G_OBJECT (action), "sensitive", can_copy, NULL);
 
518
        
 
519
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, "AddToQueue");
420
520
        g_object_set (G_OBJECT (action), "sensitive", can_add_to_queue, NULL);
421
521
        
422
 
        action = gtk_action_group_get_action (clipboard->priv->actiongroup,
423
 
                                              "MusicProperties");
424
 
        g_object_set (G_OBJECT (action), "sensitive", have_selection, NULL);
425
 
        
426
 
        action = gtk_action_group_get_action (clipboard->priv->actiongroup,
427
 
                                              "QueueMusicProperties");
428
 
        g_object_set (G_OBJECT (action), "sensitive", have_sidebar_selection, NULL);
429
 
        action = gtk_action_group_get_action (clipboard->priv->actiongroup,
430
 
                                              "QueueDelete");
431
 
        g_object_set (G_OBJECT (action), "sensitive", have_sidebar_selection, NULL);
 
522
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, "MusicProperties");
 
523
        g_object_set (G_OBJECT (action), "sensitive", have_selection, NULL);
 
524
        
 
525
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, "QueueMusicProperties");
 
526
        g_object_set (G_OBJECT (action), "sensitive", have_sidebar_selection, NULL);
 
527
        
 
528
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, "QueueDelete");
 
529
        g_object_set (G_OBJECT (action), "sensitive", have_sidebar_selection, NULL);
 
530
        
 
531
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, "EditSelectAll");
 
532
        g_object_set (G_OBJECT (action), "sensitive", can_select_all, NULL);
 
533
        
 
534
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, "EditSelectNone");
 
535
        g_object_set (G_OBJECT (action), "sensitive", have_selection, NULL);
 
536
 
 
537
        return FALSE;
432
538
}
433
539
 
434
540
static void
553
659
        did_sync = rb_shell_clipboard_process_deletions (clipboard);
554
660
 
555
661
        if (did_sync)
556
 
                clipboard->priv->idle_sync_id =
 
662
                clipboard->priv->idle_deletion_id =
557
663
                        g_idle_add_full (G_PRIORITY_LOW,
558
664
                                         (GSourceFunc) rb_shell_clipboard_idle_poll_deletions,
559
665
                                         clipboard, NULL);
560
666
        else
561
 
                clipboard->priv->idle_sync_id =
 
667
                clipboard->priv->idle_deletion_id =
562
668
                        g_timeout_add (300,
563
669
                                       (GSourceFunc) rb_shell_clipboard_idle_poll_deletions,
564
670
                                       clipboard);
582
688
rb_shell_clipboard_entryview_changed_cb (RBEntryView *view,
583
689
                                         RBShellClipboard *clipboard)
584
690
{
585
 
        rb_debug ("entryview changed");
586
 
        rb_shell_clipboard_sync (clipboard);
 
691
        if (clipboard->priv->idle_sync_id == 0)
 
692
                clipboard->priv->idle_sync_id = g_idle_add ((GSourceFunc) rb_shell_clipboard_sync,
 
693
                                                            clipboard);
 
694
        rb_debug ("entryview changed");
 
695
}
 
696
        
 
697
static void
 
698
rb_shell_clipboard_entries_changed_cb (RBEntryView *view,
 
699
                                       gpointer stuff,
 
700
                                       RBShellClipboard *clipboard)
 
701
{
 
702
        rb_debug ("entryview changed");
 
703
        if (clipboard->priv->idle_sync_id == 0)
 
704
                clipboard->priv->idle_sync_id = g_idle_add ((GSourceFunc) rb_shell_clipboard_sync,
 
705
                                                            clipboard);
 
706
}
 
707
 
 
708
static void
 
709
rb_shell_clipboard_cmd_add_to_playlist_new (GtkAction *action,
 
710
                                            RBShellClipboard *clipboard)
 
711
{
 
712
        GList *entries;
 
713
        RBSource *playlist_source;
 
714
 
 
715
        rb_debug ("add to new playlist");
 
716
        
 
717
        entries = rb_source_copy (clipboard->priv->source);
 
718
        playlist_source = rb_playlist_manager_new_playlist (clipboard->priv->playlist_manager,
 
719
                                                            NULL, FALSE);
 
720
        rb_source_paste (playlist_source, entries);
 
721
        g_list_free (entries);
587
722
}
588
723
 
589
724
static void
612
747
        rb_play_queue_source_sidebar_song_info (RB_PLAY_QUEUE_SOURCE (clipboard->priv->queue_source));
613
748
}
614
749
 
 
750
static void
 
751
rb_shell_clipboard_playlist_add_cb (GtkAction *action,
 
752
                                    RBShellClipboard *clipboard)
 
753
{
 
754
        RBSource *playlist_source;
 
755
        GList *entries;
 
756
 
 
757
        rb_debug ("add to exisintg playlist");
 
758
        playlist_source = g_object_get_data (G_OBJECT (action), "playlist-source");
 
759
        
 
760
        entries = rb_source_copy (clipboard->priv->source);
 
761
        rb_source_paste (playlist_source, entries);
 
762
        g_list_free (entries);
 
763
}
 
764
 
 
765
static char *
 
766
generate_action_name (RBStaticPlaylistSource *source,
 
767
                      RBShellClipboard *clipboard)
 
768
{
 
769
        return g_strdup_printf ("AddToPlaylistClipboardAction%p", source);
 
770
}
 
771
 
 
772
static void
 
773
rb_shell_clipboard_playlist_deleted_cb (RBStaticPlaylistSource *source,
 
774
                                        RBShellClipboard *clipboard)
 
775
{
 
776
        char *action_name;
 
777
        GtkAction *action;
 
778
        
 
779
        action_name = generate_action_name (source, clipboard);
 
780
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, action_name);
 
781
        g_assert (action);
 
782
        gtk_action_group_remove_action (clipboard->priv->actiongroup, action);
 
783
        g_free (action_name);
 
784
        g_object_unref (G_OBJECT (action));
 
785
 
 
786
        /* this will update the menu */
 
787
        if (clipboard->priv->idle_playlist_id == 0) {
 
788
                clipboard->priv->idle_playlist_id =
 
789
                        g_idle_add ((GSourceFunc)rebuild_playlist_menu, clipboard);
 
790
        }
 
791
}
 
792
 
 
793
static void
 
794
rb_shell_clipboard_playlist_renamed_cb (RBStaticPlaylistSource *source,
 
795
                                        GParamSpec *spec,
 
796
                                        RBShellClipboard *clipboard)
 
797
{
 
798
        char *name, *action_name;
 
799
        GtkAction *action;
 
800
 
 
801
        g_object_get (G_OBJECT (source), "name", &name, NULL);
 
802
 
 
803
        action_name = generate_action_name (source, clipboard);
 
804
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, action_name);
 
805
        g_assert (action);
 
806
        g_free (action_name);
 
807
        
 
808
        g_object_set (G_OBJECT (action), "label", name, NULL);
 
809
        g_free (name);
 
810
        g_object_unref (G_OBJECT (action));
 
811
}
 
812
 
 
813
static void
 
814
rb_shell_clipboard_playlist_visible_cb (RBStaticPlaylistSource *source,
 
815
                                        GParamSpec *spec,
 
816
                                        RBShellClipboard *clipboard)
 
817
{
 
818
        gboolean visible = FALSE;
 
819
        char *action_name;
 
820
        GtkAction *action;
 
821
 
 
822
        g_object_get (G_OBJECT (source), "visibility", &visible, NULL);
 
823
 
 
824
        action_name = generate_action_name (source, clipboard);
 
825
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, action_name);
 
826
        g_assert (action);
 
827
        g_free (action_name);
 
828
        
 
829
        gtk_action_set_visible (action, visible);
 
830
        g_object_unref (G_OBJECT (action));
 
831
}
 
832
 
 
833
static gboolean
 
834
add_playlist_to_menu (GtkTreeModel *model,
 
835
                      GtkTreePath *path,
 
836
                      GtkTreeIter *iter,
 
837
                      RBShellClipboard *clipboard)
 
838
{
 
839
        RhythmDBEntryType entry_type, source_entry_type;
 
840
        RBSource *source = NULL;
 
841
        char *action_name;
 
842
        GtkAction *action;
 
843
        int i;
 
844
 
 
845
        gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
 
846
                            RB_SOURCELIST_MODEL_COLUMN_SOURCE, &source, -1);
 
847
 
 
848
        if (!RB_IS_STATIC_PLAYLIST_SOURCE (source))
 
849
                return FALSE;
 
850
        entry_type = RHYTHMDB_ENTRY_TYPE_SONG;
 
851
        g_object_get (G_OBJECT (source), "entry-type", &source_entry_type, NULL);
 
852
        if (source_entry_type != entry_type)
 
853
                return FALSE;
 
854
 
 
855
        action_name = generate_action_name (RB_STATIC_PLAYLIST_SOURCE (source), clipboard);
 
856
        action = gtk_action_group_get_action (clipboard->priv->actiongroup, action_name);
 
857
        if (action == NULL) {
 
858
                char *name;
 
859
 
 
860
                g_object_get (G_OBJECT (source), "name", &name, NULL);
 
861
                action = gtk_action_new (action_name, name, NULL, NULL);
 
862
                gtk_action_group_add_action (clipboard->priv->actiongroup, action);
 
863
                g_free (name);
 
864
 
 
865
                g_object_set_data (G_OBJECT (action), "playlist-source", source);
 
866
                g_signal_connect_object (G_OBJECT (action),
 
867
                                         "activate", G_CALLBACK (rb_shell_clipboard_playlist_add_cb),
 
868
                                         clipboard, 0);
 
869
 
 
870
                g_signal_connect_object (G_OBJECT (source),
 
871
                                         "deleted", G_CALLBACK (rb_shell_clipboard_playlist_deleted_cb),
 
872
                                         clipboard, 0);
 
873
                g_signal_connect_object (G_OBJECT (source),
 
874
                                         "notify::name", G_CALLBACK (rb_shell_clipboard_playlist_renamed_cb),
 
875
                                         clipboard, 0);
 
876
                g_signal_connect_object (G_OBJECT (source),
 
877
                                         "notify::visibility", G_CALLBACK (rb_shell_clipboard_playlist_visible_cb),
 
878
                                         clipboard, 0);
 
879
        }
 
880
 
 
881
        for (i = 0; i < num_playlist_menu_paths; i++) {
 
882
                gtk_ui_manager_add_ui (clipboard->priv->ui_mgr, clipboard->priv->playlist_menu_ui_id,
 
883
                                       playlist_menu_paths[i],
 
884
                                       action_name, action_name,
 
885
                                       GTK_UI_MANAGER_AUTO, FALSE);
 
886
        }
 
887
 
 
888
        return FALSE;
 
889
}
 
890
 
 
891
static gboolean
 
892
rebuild_playlist_menu (RBShellClipboard *clipboard)
 
893
{
 
894
        GtkTreeModel *model = NULL;
 
895
        GObject *sourcelist = NULL;
 
896
 
 
897
        if (clipboard->priv->playlist_menu_ui_id != 0) {
 
898
                gtk_ui_manager_remove_ui (clipboard->priv->ui_mgr,
 
899
                                          clipboard->priv->playlist_menu_ui_id);
 
900
        } else {
 
901
                clipboard->priv->playlist_menu_ui_id =
 
902
                        gtk_ui_manager_new_merge_id (clipboard->priv->ui_mgr);
 
903
        }
 
904
 
 
905
        g_object_get (G_OBJECT (clipboard->priv->playlist_manager), "sourcelist", &sourcelist, NULL);
 
906
        g_object_get (sourcelist, "model", &model, NULL);
 
907
        g_object_unref (sourcelist);
 
908
        gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc)add_playlist_to_menu, clipboard);
 
909
        g_object_unref (G_OBJECT (model));
 
910
 
 
911
        clipboard->priv->idle_playlist_id = 0;
 
912
        return FALSE;
 
913
}
 
914
 
 
915
static void
 
916
rb_shell_clipboard_playlist_added_cb (RBPlaylistManager *mgr,
 
917
                                      RBPlaylistSource *source,
 
918
                                      RBShellClipboard *clipboard)
 
919
{
 
920
        if (!RB_IS_STATIC_PLAYLIST_SOURCE (source))
 
921
                return;
 
922
 
 
923
        if (clipboard->priv->idle_playlist_id == 0) {
 
924
                clipboard->priv->idle_playlist_id =
 
925
                        g_idle_add ((GSourceFunc)rebuild_playlist_menu, clipboard);
 
926
        }
 
927
}
 
928