TTKMusicPlayer  3.7.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 
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 const MusicPlayItemList& MusicPlaylist::mediaList() const
115 {
116  return m_mediaList;
117 }
118 
119 const MusicPlayItemList& MusicPlaylist::queueList() const
120 {
121  return m_queueList;
122 }
123 
125 {
126  return m_mediaList.count();
127 }
128 
130 {
131  return m_mediaList.isEmpty();
132 }
133 
135 {
136  m_mediaList.clear();
137  removeQueue();
138 }
139 
140 static void updatePlayItems(const TTK::IndexPropertyList &indexs, MusicPlayItemList &items)
141 {
142  for(MusicPlayItem &item : items)
143  {
144  for(const TTK::IndexProperty &index : qAsConst(indexs))
145  {
146  if(item.m_playlistRow != index.m_first)
147  {
148  continue;
149  }
150 
151  item.m_playlistRow = index.m_second;
152  break;
153  }
154  }
155 }
156 
157 void MusicPlaylist::update(const TTK::IndexPropertyList &indexs)
158 {
159  updatePlayItems(indexs, m_mediaList);
160  updatePlayItems(indexs, m_queueList);
161 }
162 
163 int MusicPlaylist::find(const MusicPlayItem &item) const
164 {
165  return m_mediaList.indexOf(item);
166 }
167 
168 int MusicPlaylist::find(int playlistRow, const QString &content, int from)
169 {
170  return m_mediaList.indexOf({playlistRow, content}, from);
171 }
172 
173 void MusicPlaylist::add(int playlistRow, const QString &content)
174 {
175  clear();
176  m_mediaList << MusicPlayItem(playlistRow, content);
177 }
178 
179 void MusicPlaylist::add(int playlistRow, const QStringList &items)
180 {
181  clear();
182  for(const QString &path : qAsConst(items))
183  {
184  m_mediaList << MusicPlayItem(playlistRow, path);
185  }
186 }
187 
188 void MusicPlaylist::append(int playlistRow, const QString &content)
189 {
190  m_mediaList << MusicPlayItem(playlistRow, content);
191 }
192 
193 void MusicPlaylist::append(int playlistRow, const QStringList &items)
194 {
195  for(const QString &path : qAsConst(items))
196  {
197  m_mediaList << MusicPlayItem(playlistRow, path);
198  }
199 }
200 
201 void MusicPlaylist::appendQueue(int playlistRow, const QString &content)
202 {
203  const int index = m_currentIndex + 1;
204  (index != m_mediaList.count()) ? m_mediaList.insert(index, {playlistRow, content})
205  : m_mediaList.append({playlistRow, content});
206  m_queueList << MusicPlayItem(index + m_queueList.count(), content);
207 }
208 
210 {
211  if(pos < 0 || pos >= m_mediaList.count())
212  {
213  return false;
214  }
215 
216  m_mediaList.removeAt(pos);
217  removeQueue();
218  return true;
219 }
220 
221 int MusicPlaylist::remove(int playlistRow, const QString &content)
222 {
223  const int index = find(playlistRow, content);
224  if(index != -1)
225  {
226  m_mediaList.removeAt(index);
227  removeQueue();
228  }
229 
230  return index;
231 }
232 
234 {
235  m_queueList.clear();
236 }
237 
238 #define GENERATE_RANDOM_INDEX(index) \
239  m_currentIndex = m_shuffle.isEnabled() ? find(m_shuffle.setCurrentIndex(index)) : (TTK::random() % m_mediaList.count());
240 
242 {
244 
245  if(index == TTK_LOW_LEVEL)
246  {
247  switch(m_playbackMode)
248  {
249  case TTK::PlayMode::OneLoop: break;
251  {
252  if(++m_currentIndex >= m_mediaList.count())
253  {
254  m_currentIndex = -1;
255  }
256  break;
257  }
259  {
260  if(++m_currentIndex >= m_mediaList.count())
261  {
262  m_currentIndex = 0;
263  }
264  break;
265  }
267  {
268  GENERATE_RANDOM_INDEX(index);
269  break;
270  }
271  case TTK::PlayMode::Once: break;
272  default: break;
273  }
274  }
275  else if(index == PLAY_NEXT_LEVEL)
276  {
278  {
279  GENERATE_RANDOM_INDEX(index);
280  }
281  else
282  {
283  int index = m_currentIndex;
284  m_currentIndex = (++index >= count()) ? 0 : index;
285  }
286  }
287  else if(index == PLAY_PREVIOUS_LEVEL)
288  {
290  {
291  GENERATE_RANDOM_INDEX(index);
292  }
293  else
294  {
295  int index = m_currentIndex;
296  m_currentIndex = (--index < 0) ? 0 : index;
297  }
298 
299  m_queueList.clear();
300  }
301  else
302  {
303  m_currentIndex = index;
304  //
306  {
308  }
309  }
310 #undef GENERATE_RANDOM_INDEX
311 
312  if(!m_queueList.isEmpty())
313  {
314  const MusicPlayItem &item = m_queueList.takeFirst();
316  if(m_currentIndex < 0 || m_currentIndex >= m_mediaList.count())
317  {
318  m_currentIndex = -1;
319  }
320  }
321 
323 }
324 
325 void MusicPlaylist::setCurrentIndex(int playlistRow, const QString &path)
326 {
327  const int playIndex = find({playlistRow, path});
328  setCurrentIndex(playIndex);
329 }
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:253
void initialize(const MusicPlayItemList &items)
QString m_path
Definition: musicplaylist.h:30
static void updatePlayItems(const TTK::IndexPropertyList &indexs, MusicPlayItemList &items)
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:204
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:182
bool remove(int pos)
#define qAsConst
Definition: ttkqtglobal.h:53
bool isEmpty() const
const MusicPlayItemList & queueList() const
The namespace of the process utils.
Definition: ttkcompat.h:24
QString currentMediaPath() const
PlayMode
Definition: musicobject.h:171
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