summaryrefslogtreecommitdiffstats
path: root/juk/upcomingplaylist.h
blob: ee0570f954cafc8546f29919a6a0c030570736d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/***************************************************************************
    begin                : Thu Aug 19 2004 
    copyright            : (C) 2002 - 2004 by Michael Pyne
    email                : michael.pyne@kde.org
***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef _UPCOMINGPLAYLIST_H
#define _UPCOMINGPLAYLIST_H


#include <qguardedptr.h>

#include "playlist.h"
#include "tracksequenceiterator.h"

class TrackSequenceManager;

/**
 * A class to implement upcoming playlist support in JuK.  It is closely
 * associated with the UpcomingSequenceIterator class.  It works by using
 * whatever iterator is currently being used by the TrackSequenceManager
 * instance when this playlist is constructed to form a list of upcoming tracks.
 * After the playlist is created, tracks are played from top to bottom until
 * the list is empty.  If loop playlist is enabled, tracks are automatically
 * added as tracks are removed.  Also, enabling this playlist causes the base
 * Playlist class to add an item to the context-menu to add the selected items
 * to this playlist.  If the user double-clicks any track to force it to play,
 * it is added to the top of this playlist automatically, replacing any
 * currently playing song.
 *
 * @author Michael Pyne <michael.pyne@kdemail.net>
 * @see UpcomingSequenceIterator
 */
class UpcomingPlaylist : public Playlist
{
public:
    /**
     * Constructor for the UpcomingPlaylist object.  You should only ever have
     * one instance of this class.  You should call the initialize() function
     * before using the created object.
     *
     * @see initialize
     * @param collection The PlaylistCollection that owns this playlist.
     * @param defaultSize The default number of tracks to place in the playlist.
     */
    UpcomingPlaylist(PlaylistCollection *collection, int defaultSize = 15);
    /**
     * Destructor for the UpcomingPlaylist.  This destructor will restore the
     * iterator for the TrackSequenceManager, and if a song is playing when
     * this playlist is removed, it will remain playing after the playlist is
     * destroyed.
     */
    virtual ~UpcomingPlaylist();

    /**
     * This function initializes the upcoming playlist, so that you can create
     * it before the GUI has been completely setup.  If a song is playing when
     * this function is called, then the song will be added to this playlist,
     * automatically with no interruption in playback.
     */
    void initialize();

    /**
     * Appends the given items to the end of the playlist.  Use this function
     * instead of createItems() since this function ensures that the items are
     * added to the end of the playlist.
     *
     * @see createItems(const PlaylistItemList &, PlaylistItem *)
     * @param itemList The list of PlaylistItems to append.
     */
    void appendItems(const PlaylistItemList &itemList);

    /**
     * Reimplemented to set the playing item in both the source playlist
     * and the upcoming playlist.
     */
    virtual void playNext();

    /**
     * Reimplemented to remove the item from the Playlist index.
     */
    virtual void clearItem(PlaylistItem *item, bool emitChanged = true);

    virtual void addFiles(const QStringList &files, PlaylistItem *after = 0);

    /**
     * Returns a reference to the index between items in the list and the
     * playlist that they came from.  This is used to remap the currently
     * playing item to the source playlist.
     */
    QMap<PlaylistItem::Pointer, QGuardedPtr<Playlist> > &playlistIndex();

    bool active() const { return m_active; }

private:

    /**
     * Internal function to restore the TrackSequenceManager to the state
     * it was in when the object was constructed, except for the playing
     * item.
     */
    void removeIteratorOverride();

    /**
     * This function returns the instance of the TrackSequenceManager.
     *
     * @return the TrackSequenceManager instance.
     * @see TrackSequenceManager::instance()
     */
    TrackSequenceManager *manager() const;

private:
    class UpcomingSequenceIterator;
    friend class UpcomingSequenceIterator;

    bool m_active;
    TrackSequenceIterator *m_oldIterator;
    int m_defaultSize;
    QMap<PlaylistItem::Pointer, QGuardedPtr<Playlist> > m_playlistIndex;
};

/**
 * An implementation of TrackSequenceIterator designed to work with
 * UpcomingPlaylist.  It is installed by UpcomingPlaylist to ensure that the
 * UpcomingPlaylist is in charge of the playback sequence.
 *
 * @see UpcomingPlaylist
 * @see TrackSequenceManager
 * @author Michael Pyne <michael.pyne@kdemail.net>
 */
class UpcomingPlaylist::UpcomingSequenceIterator : public TrackSequenceIterator
{
public:
    /**
     * Default constructor.
     *
     * @param playlist The UpcomingPlaylist this iterator belongs to.
     */
    UpcomingSequenceIterator(UpcomingPlaylist *playlist);

    /**
     * Copy constructor.
     *
     * @param other The UpcomingSequenceIterator to copy.
     */
    UpcomingSequenceIterator(const UpcomingSequenceIterator &other);

    /**
     * Destructor.
     */
    virtual ~UpcomingSequenceIterator();

    /**
     * Advances to the next song in the UpcomingPlaylist.
     */
    virtual void advance();

    /**
     * This function does nothing, as the currently playing song in the
     * UpcomingPlaylist is always the first song in the sequence.
     */
    virtual void backup();

    /**
     * This function returns a perfect duplicate of the object it is called
     * on, to avoid the C++ slicing problem.
     *
     * @return A pointer to a copy of the object it is called on.
     */
    virtual UpcomingSequenceIterator *clone() const;

    /**
     * This function sets the currently playing item to @a currentItem.  If the
     * item doesn't belong to the parent UpcomingPlaylist, it will be added to
     * the UpcomingPlaylist, replacing any track that may be playing.
     * Otherwise, it is moved up and set to play, replacing any track that may
     * be playing.
     *
     * @param currentItem The PlaylistItem to play.
     */
    virtual void setCurrent(PlaylistItem *currentItem);

    /**
     * This function resets any internet state.
     */
    virtual void reset();

    /**
     * This function readies the UpcomingSequenceIterator for playback, by
     * making sure the parent UpcomingPlaylist has items to play if it is
     * empty.
     */
    virtual void prepareToPlay(Playlist *);

private:
    UpcomingPlaylist *m_playlist;
};

QDataStream &operator<<(QDataStream &s, const UpcomingPlaylist &p);
QDataStream &operator>>(QDataStream &s, UpcomingPlaylist &p);

#endif /* _UPCOMINGPLAYLIST_H */

// vim: set et sw=4 ts=4: