TTKMusicPlayer  4.3.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
musicplaylist.cpp
Go to the documentation of this file.
1 #include "musicplaylist.h"
2 #include "musicsong.h"
3 
4 #include <random>
5 
7  : m_index(-1),
8  m_enable(false)
9 {
10 }
11 
12 void MusicPlaylist::Shuffle::setEnabled(bool enable) noexcept
13 {
14  m_enable = enable;
15 }
16 
18 {
19  return m_enable;
20 }
21 
22 void MusicPlaylist::Shuffle::initialize(const MusicPlayItemList &items) noexcept
23 {
24  if(m_enable && items.count() != m_data.count())
25  {
26  m_index = -1;
27  m_data = items;
28  std::shuffle(m_data.begin(), m_data.end(), std::default_random_engine(std::random_device()()));
29  }
30 }
31 
33 {
34  m_index = m_data.indexOf(item);
35 }
36 
38 {
39  if(m_data.isEmpty())
40  {
41  return {};
42  }
43 
44  if(index == TTK_LOW_LEVEL|| index == PLAY_NEXT_LEVEL)
45  {
46  if(++m_index >= m_data.count())
47  {
48  m_index = 0;
49  }
50  }
51  else if(index == PLAY_PREVIOUS_LEVEL)
52  {
53  if(--m_index < 0)
54  {
55  m_index = m_data.count() - 1;
56  }
57  }
58  else
59  {
60  m_index = index;
61  }
62  return m_data[m_index];
63 }
64 
65 
67  : QObject(parent),
68  m_currentIndex(-1),
69  m_playbackMode(TTK::PlayMode::Order)
70 {
72 }
73 
74 void MusicPlaylist::setShuffleMode(bool shuffle) noexcept
75 {
76  m_shuffle.setEnabled(shuffle);
77 }
78 
80 {
81  return m_playbackMode;
82 }
83 
85 {
86  m_playbackMode = mode;
87  Q_EMIT playbackModeChanged(m_playbackMode);
88 }
89 
91 {
92  return m_currentIndex;
93 }
94 
96 {
97  if(m_mediaList.isEmpty() || m_currentIndex == -1 || m_currentIndex >= m_mediaList.count())
98  {
99  return MusicPlayItem();
100  }
101  return m_mediaList[m_currentIndex];
102 }
103 
104 const MusicPlayItemList& MusicPlaylist::mediaList() const noexcept
105 {
106  return m_mediaList;
107 }
108 
109 const MusicPlayItemList& MusicPlaylist::queueList() const noexcept
110 {
111  return m_queueList;
112 }
113 
115 {
116  return m_mediaList.count();
117 }
118 
120 {
121  return m_mediaList.isEmpty();
122 }
123 
125 {
126  m_mediaList.clear();
127  removeQueue();
128 }
129 
130 static void updatePlayItems(const TTK::IndexPropertyList &rows, MusicPlayItemList &items)
131 {
132  for(MusicPlayItem &item : items)
133  {
134  for(const TTK::IndexProperty &row : qAsConst(rows))
135  {
136  if(item.m_playlistRow != row.m_first)
137  {
138  continue;
139  }
140 
141  item.m_playlistRow = row.m_second;
142  break;
143  }
144  }
145 }
146 
147 void MusicPlaylist::update(const TTK::IndexPropertyList &rows)
148 {
151 }
152 
153 int MusicPlaylist::find(const MusicPlayItem &item) const
154 {
155  return m_mediaList.indexOf(item);
156 }
157 
158 int MusicPlaylist::find(int playlistRow, const QString &content, int from)
159 {
160  return m_mediaList.indexOf({playlistRow, content}, from);
161 }
162 
163 void MusicPlaylist::add(int playlistRow, const QString &content)
164 {
165  clear();
166  m_mediaList << MusicPlayItem(playlistRow, content);
167 }
168 
169 void MusicPlaylist::add(int playlistRow, const QStringList &items)
170 {
171  clear();
172  for(const QString &path : qAsConst(items))
173  {
174  m_mediaList << MusicPlayItem(playlistRow, path);
175  }
176 }
177 
178 void MusicPlaylist::append(int playlistRow, const QString &content)
179 {
180  m_mediaList << MusicPlayItem(playlistRow, content);
181 }
182 
183 void MusicPlaylist::append(int playlistRow, const QStringList &items)
184 {
185  for(const QString &path : qAsConst(items))
186  {
187  m_mediaList << MusicPlayItem(playlistRow, path);
188  }
189 }
190 
191 void MusicPlaylist::appendQueue(int playlistRow, const QString &content)
192 {
193  const int index = m_currentIndex + 1;
194  if(index == m_mediaList.count())
195  {
196  m_mediaList.append({playlistRow, content});
197  }
198  else
199  {
200  m_mediaList.insert(index, {playlistRow, content});
201  }
202  m_queueList << MusicPlayItem(index + m_queueList.count(), content);
203 }
204 
205 bool MusicPlaylist::remove(int index)
206 {
207  if(index < 0 || index >= m_mediaList.count())
208  {
209  return false;
210  }
211 
212  m_mediaList.removeAt(index);
213  removeQueue();
214  return true;
215 }
216 
217 int MusicPlaylist::remove(int playlistRow, const QString &content)
218 {
219  const int index = find(playlistRow, content);
220  if(index != -1)
221  {
222  m_mediaList.removeAt(index);
223  removeQueue();
224  }
225 
226  return index;
227 }
228 
230 {
231  m_queueList.clear();
232 }
233 
234 #define GENERATE_RANDOM_INDEX(index) \
235  m_currentIndex = m_shuffle.isEnabled() ? find(m_shuffle.setCurrentIndex(index)) : TTK::random(m_mediaList.count());
236 
238 {
240 
241  if(index == TTK_LOW_LEVEL)
242  {
243  switch(m_playbackMode)
244  {
245  case TTK::PlayMode::OneLoop: break;
247  {
248  if(++m_currentIndex >= m_mediaList.count())
249  {
250  m_currentIndex = -1;
251  }
252  break;
253  }
255  {
256  if(++m_currentIndex >= m_mediaList.count())
257  {
258  m_currentIndex = 0;
259  }
260  break;
261  }
263  {
264  GENERATE_RANDOM_INDEX(index);
265  break;
266  }
267  case TTK::PlayMode::Once: break;
268  default: break;
269  }
270  }
271  else if(index == PLAY_NEXT_LEVEL)
272  {
274  {
275  GENERATE_RANDOM_INDEX(index);
276  }
277  else
278  {
279  int index = m_currentIndex;
280  m_currentIndex = (++index >= count()) ? 0 : index;
281  }
282  }
283  else if(index == PLAY_PREVIOUS_LEVEL)
284  {
286  {
287  GENERATE_RANDOM_INDEX(index);
288  }
289  else
290  {
291  int index = m_currentIndex;
292  m_currentIndex = (--index < 0) ? 0 : index;
293  }
294 
295  m_queueList.clear();
296  }
297  else
298  {
299  m_currentIndex = index;
300  //
302  {
304  }
305  }
306 #undef GENERATE_RANDOM_INDEX
307 
308  if(!m_queueList.isEmpty())
309  {
310  const MusicPlayItem &item = m_queueList.takeFirst();
312  if(m_currentIndex < 0 || m_currentIndex >= m_mediaList.count())
313  {
314  m_currentIndex = -1;
315  }
316  }
317 
319 }
320 
321 void MusicPlaylist::setCurrentIndex(int playlistRow, const QString &path)
322 {
323  const int playIndex = find({playlistRow, path});
324  setCurrentIndex(playIndex);
325 }
void appendQueue(int playlistRow, const QString &content)
The class of the music play item.
Definition: musicplaylist.h:27
const MusicPlayItemList & queueList() const noexcept
MusicPlaylist(QObject *parent=nullptr)
void setShuffleMode(bool shuffle) noexcept
bool isEnabled() const noexcept
#define TTK_LOW_LEVEL
Definition: ttkglobal.h:332
MusicPlayItem currentItem() const noexcept
bool isEmpty() const noexcept
TTK::PlayMode playbackMode() const noexcept
TTK_MODULE_EXPORT void initRandom()
Definition: ttktime.cpp:7
bool remove(int index)
#define GENERATE_RANDOM_INDEX(index)
MusicPlayItemList m_queueList
int find(const MusicPlayItem &item) const
The class of the index property.
Definition: musicobject.h:223
void add(int playlistRow, const QString &content)
static constexpr int PLAY_PREVIOUS_LEVEL
Definition: musicplaylist.h:58
#define qAsConst
Definition: ttkqtglobal.h:57
void removeQueue() noexcept
The namespace of the application object.
Definition: ttkcompat.h:24
PlayMode
Definition: musicobject.h:190
void currentIndexChanged(int index)
MusicPlayItemList m_mediaList
static constexpr int PLAY_NEXT_LEVEL
Definition: musicplaylist.h:57
void setPlaybackMode(TTK::PlayMode mode) noexcept
void setCurrentIndex(int index)
int count() const noexcept
class MusicPlaylist::Shuffle m_shuffle
TTK::PlayMode m_playbackMode
static void updatePlayItems(const TTK::IndexPropertyList &rows, MusicPlayItemList &items)
int currentIndex() const noexcept
void append(int playlistRow, const QString &content)
void setCurrentIndex(const MusicPlayItem &item) noexcept
const MusicPlayItemList & mediaList() const noexcept
void initialize(const MusicPlayItemList &items) noexcept
const char int mode
Definition: ioapi.h:135
#define const
Definition: zconf.h:233
void update(const TTK::IndexPropertyList &rows)
void setEnabled(bool enable) noexcept