TTKMusicPlayer  4.1.3.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 
13 {
14  m_enable = enable;
15 }
16 
18 {
19  return m_enable;
20 }
21 
22 void MusicPlaylist::Shuffle::initialize(const MusicPlayItemList &items)
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 
75 {
76  m_shuffle.setEnabled(shuffle);
77 }
78 
80 {
81  return m_playbackMode;
82 }
83 
85 {
88 }
89 
91 {
92  return m_currentIndex;
93 }
94 
96 {
97  if(m_currentIndex == -1 || m_currentIndex >= m_mediaList.count())
98  {
99  return MusicPlayItem();
100  }
101  return m_mediaList.isEmpty() ? MusicPlayItem() : m_mediaList[m_currentIndex];
102 }
103 
105 {
106  const MusicPlayItem &item = currentItem();
108  {
110  }
111  return item.m_path;
112 }
113 
114 bool MusicPlaylist::isSameMediaPath(const QString &path) const
115 {
116  const MusicPlayItem &item = currentItem();
118  {
120  }
121  return item.m_path == path;
122 }
123 
124 const MusicPlayItemList& MusicPlaylist::mediaList() const
125 {
126  return m_mediaList;
127 }
128 
129 const MusicPlayItemList& MusicPlaylist::queueList() const
130 {
131  return m_queueList;
132 }
133 
135 {
136  return m_mediaList.count();
137 }
138 
140 {
141  return m_mediaList.isEmpty();
142 }
143 
145 {
146  m_mediaList.clear();
147  removeQueue();
148 }
149 
150 static void updatePlayItems(const TTK::IndexPropertyList &indexs, MusicPlayItemList &items)
151 {
152  for(MusicPlayItem &item : items)
153  {
154  for(const TTK::IndexProperty &index : qAsConst(indexs))
155  {
156  if(item.m_playlistRow != index.m_first)
157  {
158  continue;
159  }
160 
161  item.m_playlistRow = index.m_second;
162  break;
163  }
164  }
165 }
166 
167 void MusicPlaylist::update(const TTK::IndexPropertyList &indexs)
168 {
169  updatePlayItems(indexs, m_mediaList);
170  updatePlayItems(indexs, m_queueList);
171 }
172 
173 int MusicPlaylist::find(const MusicPlayItem &item) const
174 {
175  return m_mediaList.indexOf(item);
176 }
177 
178 int MusicPlaylist::find(int playlistRow, const QString &content, int from)
179 {
180  return m_mediaList.indexOf({playlistRow, content}, from);
181 }
182 
183 void MusicPlaylist::add(int playlistRow, const QString &content)
184 {
185  clear();
186  m_mediaList << MusicPlayItem(playlistRow, content);
187 }
188 
189 void MusicPlaylist::add(int playlistRow, const QStringList &items)
190 {
191  clear();
192  for(const QString &path : qAsConst(items))
193  {
194  m_mediaList << MusicPlayItem(playlistRow, path);
195  }
196 }
197 
198 void MusicPlaylist::append(int playlistRow, const QString &content)
199 {
200  m_mediaList << MusicPlayItem(playlistRow, content);
201 }
202 
203 void MusicPlaylist::append(int playlistRow, const QStringList &items)
204 {
205  for(const QString &path : qAsConst(items))
206  {
207  m_mediaList << MusicPlayItem(playlistRow, path);
208  }
209 }
210 
211 void MusicPlaylist::appendQueue(int playlistRow, const QString &content)
212 {
213  const int index = m_currentIndex + 1;
214  (index != m_mediaList.count()) ? m_mediaList.insert(index, {playlistRow, content})
215  : m_mediaList.append({playlistRow, content});
216  m_queueList << MusicPlayItem(index + m_queueList.count(), content);
217 }
218 
220 {
221  if(pos < 0 || pos >= m_mediaList.count())
222  {
223  return false;
224  }
225 
226  m_mediaList.removeAt(pos);
227  removeQueue();
228  return true;
229 }
230 
231 int MusicPlaylist::remove(int playlistRow, const QString &content)
232 {
233  const int index = find(playlistRow, content);
234  if(index != -1)
235  {
236  m_mediaList.removeAt(index);
237  removeQueue();
238  }
239 
240  return index;
241 }
242 
244 {
245  m_queueList.clear();
246 }
247 
248 #define GENERATE_RANDOM_INDEX(index) \
249  m_currentIndex = m_shuffle.isEnabled() ? find(m_shuffle.setCurrentIndex(index)) : (TTK::random() % m_mediaList.count());
250 
252 {
254 
255  if(index == TTK_LOW_LEVEL)
256  {
257  switch(m_playbackMode)
258  {
259  case TTK::PlayMode::OneLoop: break;
261  {
262  if(++m_currentIndex >= m_mediaList.count())
263  {
264  m_currentIndex = -1;
265  }
266  break;
267  }
269  {
270  if(++m_currentIndex >= m_mediaList.count())
271  {
272  m_currentIndex = 0;
273  }
274  break;
275  }
277  {
278  GENERATE_RANDOM_INDEX(index);
279  break;
280  }
281  case TTK::PlayMode::Once: break;
282  default: break;
283  }
284  }
285  else if(index == PLAY_NEXT_LEVEL)
286  {
288  {
289  GENERATE_RANDOM_INDEX(index);
290  }
291  else
292  {
293  int index = m_currentIndex;
294  m_currentIndex = (++index >= count()) ? 0 : index;
295  }
296  }
297  else if(index == PLAY_PREVIOUS_LEVEL)
298  {
300  {
301  GENERATE_RANDOM_INDEX(index);
302  }
303  else
304  {
305  int index = m_currentIndex;
306  m_currentIndex = (--index < 0) ? 0 : index;
307  }
308 
309  m_queueList.clear();
310  }
311  else
312  {
313  m_currentIndex = index;
314  //
316  {
318  }
319  }
320 #undef GENERATE_RANDOM_INDEX
321 
322  if(!m_queueList.isEmpty())
323  {
324  const MusicPlayItem &item = m_queueList.takeFirst();
326  if(m_currentIndex < 0 || m_currentIndex >= m_mediaList.count())
327  {
328  m_currentIndex = -1;
329  }
330  }
331 
333 }
334 
335 void MusicPlaylist::setCurrentIndex(int playlistRow, const QString &path)
336 {
337  const int playIndex = find({playlistRow, path});
338  setCurrentIndex(playIndex);
339 }
void appendQueue(int playlistRow, const QString &content)
The class of the music play item.
Definition: musicplaylist.h:27
void playbackModeChanged(TTK::PlayMode mode)
MusicPlaylist(QObject *parent=nullptr)
int count() const
#define TTK_LOW_LEVEL
Definition: ttkglobal.h:258
void initialize(const MusicPlayItemList &items)
QString m_path
Definition: musicplaylist.h:30
static void updatePlayItems(const TTK::IndexPropertyList &indexs, MusicPlayItemList &items)
bool isSameMediaPath(const QString &path) const
TTK_MODULE_EXPORT void initRandom()
Definition: ttktime.cpp:7
#define GENERATE_RANDOM_INDEX(index)
MusicPlayItemList m_queueList
int find(const MusicPlayItem &item) const
The class of the index property.
Definition: musicobject.h:206
void add(int playlistRow, const QString &content)
TTK::PlayMode playbackMode() const
MusicPlayItem currentItem() const
static constexpr int PLAY_PREVIOUS_LEVEL
Definition: musicplaylist.h:58
TTK_MODULE_EXPORT QString generateNetworkSongPath(const QString &path)
Definition: musicsong.cpp:175
bool remove(int pos)
#define qAsConst
Definition: ttkqtglobal.h:51
bool isEmpty() const
const MusicPlayItemList & queueList() const
The namespace of the process utils.
Definition: ttkcompat.h:24
QString currentMediaPath() const
PlayMode
Definition: musicobject.h:173
int currentIndex() const
void setCurrentIndex(const MusicPlayItem &item)
void currentIndexChanged(int index)
void setPlaybackMode(TTK::PlayMode mode)
MusicPlayItemList m_mediaList
static constexpr int PLAY_NEXT_LEVEL
Definition: musicplaylist.h:57
void setCurrentIndex(int index)
class MusicPlaylist::Shuffle m_shuffle
TTK::PlayMode m_playbackMode
void update(const TTK::IndexPropertyList &indexs)
#define MUSIC_NETWORK_LIST
void append(int playlistRow, const QString &content)
const char int mode
Definition: ioapi.h:135
void setShuffleMode(bool shuffle)
void setEnabled(bool enable)
const MusicPlayItemList & mediaList() const