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

« back to all changes in this revision

Viewing changes to shell/rb-play-order.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:
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
 
63
63
                                          GtkTreePath *path,
64
64
                                          GtkTreeIter *iter,
65
65
                                          RBPlayOrder *porder);
66
 
static void rb_play_order_entry_deleted_cb (GtkTreeModel *model,
67
 
                                            GtkTreePath *path,
68
 
                                            RBPlayOrder *porder);
 
66
static void rb_play_order_row_deleted_cb (GtkTreeModel *model,
 
67
                                          GtkTreePath *path,
 
68
                                          RBPlayOrder *porder);
69
69
static void rb_play_order_query_model_changed_cb (GObject *source, 
70
70
                                                  GParamSpec *arg,
71
71
                                                  RBPlayOrder *porder);
79
79
        RhythmDBQueryModel *query_model;
80
80
        RhythmDBEntry *playing_entry;
81
81
        gulong query_model_change_id;
 
82
        gulong sync_playing_entry_id;
82
83
        gboolean have_next;
83
84
        gboolean have_previous;
84
85
};
94
95
 
95
96
enum
96
97
{
97
 
        PLAYING_ENTRY_REMOVED,
98
98
        HAVE_NEXT_PREVIOUS_CHANGED,
99
99
        LAST_SIGNAL
100
100
};
132
132
                                                               "Playing entry",
133
133
                                                               G_PARAM_READWRITE));
134
134
        
135
 
        rb_play_order_signals[PLAYING_ENTRY_REMOVED] =
136
 
                g_signal_new ("playing_entry_removed",
137
 
                              G_OBJECT_CLASS_TYPE (object_class),
138
 
                              G_SIGNAL_RUN_LAST,
139
 
                              G_STRUCT_OFFSET (RBPlayOrderClass, playing_entry_removed),
140
 
                              NULL, NULL,
141
 
                              g_cclosure_marshal_VOID__POINTER,
142
 
                              G_TYPE_NONE,
143
 
                              1, G_TYPE_POINTER);
144
135
        rb_play_order_signals[HAVE_NEXT_PREVIOUS_CHANGED] =
145
136
                g_signal_new ("have_next_previous_changed",
146
137
                              G_OBJECT_CLASS_TYPE (object_class),
187
178
                                                      G_CALLBACK (rb_play_order_entry_added_cb),
188
179
                                                      porder);
189
180
                g_signal_handlers_disconnect_by_func (G_OBJECT (porder->priv->query_model),
190
 
                                                      G_CALLBACK (rb_play_order_entry_deleted_cb),
 
181
                                                      G_CALLBACK (rb_play_order_row_deleted_cb),
191
182
                                                      porder);
192
183
        }
193
184
 
495
486
                                                      rb_play_order_entry_added_cb,
496
487
                                                      porder);
497
488
                g_signal_handlers_disconnect_by_func (G_OBJECT (porder->priv->query_model),
498
 
                                                      rb_play_order_entry_deleted_cb,
 
489
                                                      rb_play_order_row_deleted_cb,
499
490
                                                      porder);
500
491
                g_object_unref (porder->priv->query_model);
501
492
                porder->priv->query_model = NULL;
503
494
 
504
495
        if (new_model != NULL) {
505
496
                porder->priv->query_model = new_model;
506
 
                g_object_ref (G_OBJECT (porder->priv->query_model));
507
497
                g_signal_connect_object (G_OBJECT (porder->priv->query_model),
508
498
                                         "row-inserted",
509
499
                                         G_CALLBACK (rb_play_order_entry_added_cb),
510
500
                                         porder, 0);
511
501
                g_signal_connect_object (G_OBJECT (porder->priv->query_model),
512
502
                                         "row-deleted",
513
 
                                         G_CALLBACK (rb_play_order_entry_deleted_cb),
 
503
                                         G_CALLBACK (rb_play_order_row_deleted_cb),
514
504
                                         porder, 0);
515
505
        }
516
506
 
545
535
}
546
536
 
547
537
/**
548
 
 * rb_play_order_entry_removed_cb:
 
538
 * rb_play_order_row_deleted_cb:
549
539
 * @model: #GtkTreeModel
550
 
 * @path: #GtkTreePath for removed entry
 
540
 * @entry: the #RhythmDBEntry removed from the model
551
541
 * @porder: #RBPlayOrder instance
552
542
 *
553
 
 * Called when a new entry is removed from the active #RhythmDBQueryModel.
 
543
 * Called when an entry is removed from the active #RhythmDBQueryModel.
554
544
 * Subclasses should implement entry_removed() to make any necessary 
555
545
 * changes if they store any state based on the contents of the 
556
546
 * #RhythmDBQueryModel.
559
549
 * signal is emitted.
560
550
 */
561
551
static void
562
 
rb_play_order_entry_deleted_cb (GtkTreeModel *model, GtkTreePath *path, RBPlayOrder *porder)
 
552
rb_play_order_row_deleted_cb (GtkTreeModel *model, GtkTreePath *row, RBPlayOrder *porder)
563
553
{
564
554
        RhythmDBEntry *entry;
565
 
        GtkTreeIter iter;
566
 
        
567
 
        gtk_tree_model_get_iter (model, &iter, path);
568
 
        entry = rhythmdb_query_model_iter_to_entry(RHYTHMDB_QUERY_MODEL (model),
569
 
                                                   &iter);
570
555
 
 
556
        entry = rhythmdb_query_model_tree_path_to_entry (RHYTHMDB_QUERY_MODEL (model), row);
571
557
        if (entry == porder->priv->playing_entry) {
572
 
                rb_debug ("signaling playing_entry_removed");
573
 
                g_signal_emit (G_OBJECT (porder), rb_play_order_signals[PLAYING_ENTRY_REMOVED],
574
 
                               0, entry);
 
558
                RB_PLAY_ORDER_GET_CLASS (porder)->playing_entry_removed (porder, entry);
575
559
        }
576
 
        
 
560
 
577
561
        if (RB_PLAY_ORDER_GET_CLASS (porder)->entry_removed)
578
562
                RB_PLAY_ORDER_GET_CLASS (porder)->entry_removed (porder, entry);
579
563
 
580
564
        if (!rhythmdb_query_model_has_pending_changes (RHYTHMDB_QUERY_MODEL (model)))
581
565
                rb_play_order_update_have_next_previous (porder);
 
566
 
582
567
}
583
568
 
584
569
static gboolean
593
578
        return rb_play_order_get_previous (porder) != NULL;
594
579
}
595
580
 
 
581
static gboolean
 
582
sync_playing_entry_cb (RBPlayOrder *porder)
 
583
{
 
584
        RBShellPlayer *player = rb_play_order_get_player (porder);
 
585
        if (porder->priv->playing_entry) {
 
586
                rb_shell_player_play_entry (player,
 
587
                                            porder->priv->playing_entry,
 
588
                                            rb_play_order_get_source (porder));
 
589
        } else {
 
590
                /* Just try to play something.  This is mostly here to make
 
591
                 * the play queue work correctly, but it might be helpful otherwise.
 
592
                 */
 
593
                GError *error = NULL;
 
594
                if (!rb_shell_player_do_next (player, &error)) {
 
595
                        if (error->domain != RB_SHELL_PLAYER_ERROR ||
 
596
                            error->code != RB_SHELL_PLAYER_ERROR_END_OF_PLAYLIST)
 
597
                                g_warning ("sync_playing_entry_cb: Unhandled error: %s", error->message);
 
598
                }
 
599
        }
 
600
        porder->priv->sync_playing_entry_id = 0;
 
601
        return FALSE;
 
602
}
 
603
 
596
604
static void
597
605
default_playing_entry_removed (RBPlayOrder *porder, RhythmDBEntry *entry)
598
606
{
599
607
        RBShellPlayer *player = rb_play_order_get_player (porder);
 
608
        RBSource *source = rb_shell_player_get_playing_source (player);
 
609
 
 
610
        rb_debug ("playing entry removed");
600
611
 
601
612
        /* only clear the playing source if the source this play order is using
602
613
         * is currently playing.
603
614
         */
604
 
        if (rb_shell_player_get_playing_source (player) == rb_play_order_get_source (porder))
605
 
                rb_shell_player_set_playing_source (rb_play_order_get_player (porder), NULL);
606
 
 
607
 
        rb_play_order_set_playing_entry (porder, NULL);
 
615
        if (source == rb_play_order_get_source (porder)) {      
 
616
                switch (rb_source_handle_eos (source)) {
 
617
                case RB_SOURCE_EOF_ERROR:
 
618
                case RB_SOURCE_EOF_STOP:
 
619
                case RB_SOURCE_EOF_RETRY:
 
620
                        /* stop playing */
 
621
                        rb_shell_player_set_playing_source (player, NULL);
 
622
                        break;
 
623
                case RB_SOURCE_EOF_NEXT:
 
624
                        {
 
625
                                RhythmDBEntry *next_entry;
 
626
 
 
627
                                /* go to next song, in an idle function so that other handlers run first */
 
628
                                next_entry = rb_play_order_get_next (porder);
 
629
                                if (next_entry == entry)
 
630
                                        next_entry = NULL;
 
631
 
 
632
                                g_object_set (G_OBJECT (porder), "playing-entry", next_entry, NULL);
 
633
                                if (porder->priv->sync_playing_entry_id == 0) {
 
634
                                        porder->priv->sync_playing_entry_id = 
 
635
                                                g_idle_add_full (G_PRIORITY_HIGH_IDLE, 
 
636
                                                                 (GSourceFunc) sync_playing_entry_cb, 
 
637
                                                                 porder, 
 
638
                                                                 NULL);
 
639
                                }
 
640
                                break;
 
641
                        }
 
642
                }
 
643
        } else {
 
644
                rb_play_order_set_playing_entry (porder, NULL);
 
645
        }
608
646
}
609
647
 
610
648
/**