TTKMusicPlayer  3.7.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
musicttkfmradioplaywidget.cpp
Go to the documentation of this file.
2 #include "ui_musicttkfmradioplaywidget.h"
3 #include "ui_musicttkfmradioinformationwidget.h"
4 #include "musiccoremplayer.h"
5 #include "musictoastlabel.h"
6 #include "musicmessagebox.h"
7 #include "ttkitemdelegate.h"
8 
9 #include <QScrollBar>
10 
11 #define FMRADIO_PATH RESOURCE_DIR_FULL + "fmlist"
12 
14  : TTKAbstractXml()
15 {
16 
17 }
18 
19 bool MusicFMConfigManager::readBuffer(MusicFMCategoryList &items)
20 {
21  const QDomNodeList &nodes = m_document->elementsByTagName("category");
22  for(int i = 0; i < nodes.count(); ++i)
23  {
24  MusicFMCategory category;
25  const QDomNode &node = nodes.item(i);
26  category.m_category = node.toElement().attribute("value");
27 
28  const QDomNodeList &chnNodes = node.childNodes();
29  for(int j = 0; j < chnNodes.count(); ++j)
30  {
31  const QDomElement &element = chnNodes.item(j).toElement();
32 
33  MusicFMChannel item;
34  item.m_name = element.attribute("name");
35  item.m_location = element.attribute("location");
36  item.m_url = element.attribute("url");
37  category.m_items << item;
38  }
39  items.append(category);
40  }
41 
42  return true;
43 }
44 
45 bool MusicFMConfigManager::writeBuffer(const MusicFMCategoryList &items)
46 {
47  if(items.isEmpty())
48  {
49  return false;
50  }
51 
53  QDomElement rootDom = createRoot(TTK_APP_NAME);
54 
55  for(const MusicFMCategory &item : qAsConst(items))
56  {
57  QDomElement categoryDom = writeDomElement(rootDom, "category", {"value", item.m_category});
58 
59  for(const MusicFMChannel &channel : qAsConst(item.m_items))
60  {
61  writeDomMultiElement(categoryDom, "channel", {{"name", channel.m_name},
62  {"location", channel.m_location},
63  {"url", channel.m_url}});
64  }
65  }
66 
67  save();
68  return true;
69 }
70 
71 
73  : MusicAbstractMoveDialog(parent),
75  m_readOnly(true)
76 {
77  m_ui->setupUi(this);
78  setFixedSize(size());
79  setBackgroundLabel(m_ui->background);
80 
81  m_ui->topTitleCloseButton->setIcon(QIcon(":/functions/btn_close_hover"));
82  m_ui->topTitleCloseButton->setStyleSheet(TTK::UI::ToolButtonStyle04);
83  m_ui->topTitleCloseButton->setCursor(QCursor(Qt::PointingHandCursor));
84  m_ui->topTitleCloseButton->setToolTip(tr("Close"));
85  connect(m_ui->topTitleCloseButton, SIGNAL(clicked()), SLOT(close()));
86 
87  m_ui->button->setStyleSheet(TTK::UI::PushButtonStyle04);
88 #ifdef Q_OS_UNIX
89  m_ui->button->setFocusPolicy(Qt::NoFocus);
90 #endif
91  connect(m_ui->button, SIGNAL(clicked()), SLOT(accept()));
92 }
93 
95 {
96  delete m_ui;
97 }
98 
100 {
101  m_ui->pathEdit->setText(channel.m_url);
102  m_ui->nameEdit->setText(channel.m_name);
103  m_ui->locationEdit->setText(channel.m_location);
104 }
105 
107 {
108  return {m_ui->nameEdit->text(), m_ui->locationEdit->text(), m_ui->pathEdit->text()};
109 }
110 
112 {
113  m_readOnly = mode;
114  m_ui->pathEdit->setReadOnly(mode);
115  m_ui->nameEdit->setReadOnly(mode);
116  m_ui->locationEdit->setReadOnly(mode);
117 }
118 
119 
120 
122  : MusicAbstractMoveWidget(parent),
123  m_ui(new Ui::MusicTTKFMRadioPlayWidget),
124  m_isPlaying(false),
125  m_statusChanged(false),
126  m_currentIndex(0)
127 {
128  m_ui->setupUi(this);
129  setFixedSize(size());
130  setBackgroundLabel(m_ui->background);
131 
132  m_ui->topTitleCloseButton->setIcon(QIcon(":/functions/btn_close_hover"));
133  m_ui->topTitleCloseButton->setStyleSheet(TTK::UI::ToolButtonStyle04);
134  m_ui->topTitleCloseButton->setCursor(QCursor(Qt::PointingHandCursor));
135  m_ui->topTitleCloseButton->setToolTip(tr("Close"));
136  connect(m_ui->topTitleCloseButton, SIGNAL(clicked()), SLOT(close()));
137 
138  m_ui->playButton->setIcon(QIcon(":/functions/btn_play_hover"));
139  m_ui->previousButton->setIcon(QIcon(":/functions/btn_previous_hover"));
140  m_ui->nextButton->setIcon(QIcon(":/functions/btn_next_hover"));
141 
142  m_ui->playButton->setStyleSheet(TTK::UI::BackgroundStyle01);
143  m_ui->previousButton->setStyleSheet(TTK::UI::BackgroundStyle01);
144  m_ui->nextButton->setStyleSheet(TTK::UI::BackgroundStyle01);
145  m_ui->addButton->setStyleSheet(TTK::UI::PushButtonStyle04);
146  m_ui->deleteButton->setStyleSheet(TTK::UI::PushButtonStyle04);
147  m_ui->infoButton->setStyleSheet(TTK::UI::PushButtonStyle04);
148 
149 #ifdef Q_OS_UNIX
150  m_ui->playButton->setFocusPolicy(Qt::NoFocus);
151  m_ui->previousButton->setFocusPolicy(Qt::NoFocus);
152  m_ui->nextButton->setFocusPolicy(Qt::NoFocus);
153  m_ui->addButton->setFocusPolicy(Qt::NoFocus);
154  m_ui->deleteButton->setFocusPolicy(Qt::NoFocus);
155  m_ui->infoButton->setFocusPolicy(Qt::NoFocus);
156 #endif
157 
158  m_ui->playButton->setIconSize(QSize(31, 31));
159  m_ui->previousButton->setIconSize(QSize(31, 31));
160  m_ui->nextButton->setIconSize(QSize(31, 31));
161 
162  m_ui->playButton->setCursor(QCursor(Qt::PointingHandCursor));
163  m_ui->previousButton->setCursor(QCursor(Qt::PointingHandCursor));
164  m_ui->nextButton->setCursor(QCursor(Qt::PointingHandCursor));
165  m_ui->addButton->setCursor(QCursor(Qt::PointingHandCursor));
166  m_ui->deleteButton->setCursor(QCursor(Qt::PointingHandCursor));
167  m_ui->infoButton->setCursor(QCursor(Qt::PointingHandCursor));
168 
169  m_ui->volumeSlider->setStyleSheet(TTK::UI::SliderStyle10);
170  m_ui->volumeSlider->setRange(0, 100);
171  m_ui->volumeSlider->setValue(100);
172 
173  m_ui->itemTree->setHeaderLabels({{}, {}});
174  m_ui->itemTree->setColumnWidth(0, 220);
175  m_ui->itemTree->setColumnWidth(1, 100);
176 
177  m_ui->itemTree->header()->setVisible(false);
178  m_ui->itemTree->setStyleSheet(TTK::UI::ColorStyle02);
179  m_ui->itemTree->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
180  m_ui->itemTree->verticalScrollBar()->setStyleSheet(TTK::UI::ScrollBarStyle03);
181  m_ui->itemTree->setFocusPolicy(Qt::NoFocus);
182 
183  TTKLabelItemDelegate *delegateTitle = new TTKLabelItemDelegate(this);
185  delegateTitle->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
187  m_ui->itemTree->setItemDelegateForColumn(0, delegateTitle);
188 
189  TTKLabelItemDelegate *delegateName = new TTKLabelItemDelegate(this);
191  delegateName->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
193  m_ui->itemTree->setItemDelegateForColumn(1, delegateName);
194 
195  initialize();
197 
198  connect(m_ui->playButton, SIGNAL(clicked()), SLOT(radioPlay()));
199  connect(m_ui->previousButton, SIGNAL(clicked()), SLOT(radioPrevious()));
200  connect(m_ui->nextButton, SIGNAL(clicked()), SLOT(radioNext()));
201  connect(m_ui->addButton, SIGNAL(clicked()), SLOT(addButtonClicked()));
202  connect(m_ui->deleteButton, SIGNAL(clicked()), SLOT(deleteButtonClicked()));
203  connect(m_ui->infoButton, SIGNAL(clicked()), SLOT(infoButtonClicked()));
204  connect(m_ui->volumeSlider, SIGNAL(valueChanged(int)), SLOT(radioVolume(int)));
205  connect(m_ui->itemTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), SLOT(radioItemChanged(QTreeWidgetItem*,int)));
206 }
207 
209 {
210  delete m_player;
211  delete m_ui;
212 }
213 
214 void MusicTTKFMRadioPlayWidget::radioItemChanged(QTreeWidgetItem *item, int column)
215 {
216  if(item && column == 0)
217  {
218  const int index = indexValid(item);
219  if(index < 0)
220  {
221  return;
222  }
223 
224  m_currentIndex = index;
225  startCoreModule();
226  }
227 }
228 
230 {
231  if(TTK_LOW_LEVEL == code)
232  {
233  startCoreModule();
234  }
235 }
236 
238 {
239  if(!m_player)
240  {
241  return;
242  }
243 
245  m_ui->playButton->setIcon(QIcon(m_isPlaying ? ":/functions/btn_pause_hover" : ":/functions/btn_play_hover"));
246  m_player->play();
247 }
248 
250 {
251  if(--m_currentIndex < 0)
252  {
253  m_currentIndex = 0;
254  }
255 
256  startCoreModule();
257 }
258 
260 {
261  if(++m_currentIndex >= m_items.count())
262  {
263  m_currentIndex = 0;
264  }
265 
266  startCoreModule();
267 }
268 
270 {
271  if(m_player)
272  {
273  m_player->setVolume(num);
274  }
275 }
276 
278 {
279  delete m_player;
280  m_player = nullptr;
281 
282  MusicFMCategoryList categorys;
283  MusicFMConfigManager manager;
284  if(m_statusChanged && manager.fromFile(FMRADIO_PATH))
285  {
286  manager.readBuffer(categorys);
287 
288  if(!categorys.isEmpty())
289  {
290  categorys.back().m_items = m_favItems;
291  manager.reset();
292  manager.writeBuffer(categorys);
293  }
294  }
295 
296  QWidget::closeEvent(event);
297 }
298 
300 {
301  MusicFMCategoryList categorys;
302  {
303  MusicFMConfigManager manager;
304  if(manager.fromFile(FMRADIO_PATH))
305  {
306  manager.readBuffer(categorys);
307  }
308  }
309 
310  int index = 0;
311  for(const MusicFMCategory &category : qAsConst(categorys))
312  {
313  QTreeWidgetItem *item = new QTreeWidgetItem(m_ui->itemTree);
314  item->setData(0, TTK_DISPLAY_ROLE, category.m_category);
315  m_ui->itemTree->addTopLevelItem(item);
316 
317  for(const MusicFMChannel &channel : qAsConst(category.m_items))
318  {
319  QTreeWidgetItem *it = new QTreeWidgetItem(item);
320  it->setData(0, TTK_DATA_ROLE, index++);
321  it->setData(0, TTK_DISPLAY_ROLE, channel.m_name);
322  it->setData(1, TTK_DISPLAY_ROLE, channel.m_location);
323  }
324  m_items << category.m_items;
325  }
326 
327  if(!categorys.isEmpty())
328  {
329  m_favItems = categorys.back().m_items;
330  }
331 
333 
335  const int v = m_ui->volumeSlider->value();
336  m_ui->volumeSlider->setValue(0);
337  m_ui->volumeSlider->setValue(v);
339  m_ui->gifLabel_1->setType(MusicGifLabelWidget::Module::RadioBlue);
340  m_ui->gifLabel_2->setType(MusicGifLabelWidget::Module::RadioBlue);
341  m_ui->gifLabel_3->setType(MusicGifLabelWidget::Module::RadioBlue);
342  m_ui->gifLabel_4->setType(MusicGifLabelWidget::Module::RadioBlue);
343  m_ui->gifLabel_5->setType(MusicGifLabelWidget::Module::RadioBlue);
344 }
345 
347 {
348  m_player = new MusicCoreMPlayer(this);
349 
350  connect(m_player, SIGNAL(positionChanged(qint64)), SLOT(positionChanged(qint64)));
351  connect(m_player, SIGNAL(finished(int)), SLOT(mediaPlayFinished(int)));
352 }
353 
355 {
356  m_isPlaying = false;
357  if(!m_player)
358  {
360  }
361 
363  radioPlay();
364 
365  m_ui->titleWidget->setText(m_items[m_currentIndex].m_name);
366  m_ui->gifLabel_1->start();
367  m_ui->gifLabel_2->start();
368  m_ui->gifLabel_3->start();
369  m_ui->gifLabel_4->start();
370  m_ui->gifLabel_5->start();
371 
372  positionChanged(0);
373  m_isPlaying = true;
374 }
375 
376 int MusicTTKFMRadioPlayWidget::indexValid(QTreeWidgetItem *item) const
377 {
378  if(!item)
379  {
380  return -1;
381  }
382 
383  bool ok = false;
384  const int index = item->data(0, TTK_DATA_ROLE).toInt(&ok);
385  if(!ok || index < 0 || index >= m_items.count())
386  {
387  return -1;
388  }
389 
390  return index;
391 }
392 
394 {
395  if(!m_player)
396  {
397  return;
398  }
399 
400  m_ui->positionLabel->setText(QString("%1").arg(TTKTime::formatDuration(position * TTK_DN_S2MS)));
401 }
402 
404 {
406  w.setReadOnly(false);
407  if(w.exec())
408  {
409  const MusicFMChannel &channel = w.channelInformation();
410 
411  m_items << channel;
412  m_favItems << channel;
413  QTreeWidgetItem *item = m_ui->itemTree->topLevelItem(m_ui->itemTree->topLevelItemCount() - 1);
414  if(!item)
415  {
416  return;
417  }
418 
419  QTreeWidgetItem *it = new QTreeWidgetItem(item);
420  it->setData(0, TTK_DATA_ROLE, m_items.count() - 1);
421  it->setData(0, TTK_DISPLAY_ROLE, channel.m_name);
422  it->setData(1, TTK_DISPLAY_ROLE, channel.m_location);
423 
424  m_statusChanged = true;
425  MusicToastLabel::popup(tr("Add current channel success"));
426  }
427 }
428 
430 {
431  MusicMessageBox message;
432  message.setText(tr("Are you sure to delete?"));
433  if(!message.exec())
434  {
435  return;
436  }
437 
438  QTreeWidgetItem *item = m_ui->itemTree->currentItem();
439  const int index = indexValid(item);
440  if(index < 0)
441  {
442  return;
443  }
444 
445  const int offset = m_items.count() - m_favItems.count();
446  if(index < offset)
447  {
448  MusicToastLabel::popup(tr("The current channel can not be deleted"));
449  return;
450  }
451 
452  for(int i = index - offset + 1; i < item->parent()->childCount(); ++i)
453  {
454  item->parent()->child(i)->setData(0, TTK_DATA_ROLE, offset + i - 1);
455  }
456 
457  item->parent()->removeChild(item);
458  m_items.removeAt(index);
459  m_favItems.removeAt(index - offset);
460 
461  if(m_currentIndex == index)
462  {
463  radioPrevious();
464  }
465 
466  m_statusChanged = true;
467  MusicToastLabel::popup(tr("Delete current channel success"));
468 }
469 
471 {
472  const int index = indexValid(m_ui->itemTree->currentItem());
473  if(index < 0)
474  {
475  return;
476  }
477 
479  widget.setChannelInformation(m_items[index]);
480  widget.exec();
481 }
void setBackgroundLabel(QLabel *label)
The class of the ttk xml interface.
The class of the label item delegate.
void setText(const QString &text) const
#define TTK_DISPLAY_ROLE
QDomDocument * m_document
#define TTK_LOW_LEVEL
Definition: ttkglobal.h:253
static const QString SliderStyle10
MusicFMChannelList m_items
bool fromFile(const QString &name)
The class of the fm config manager.
virtual void closeEvent(QCloseEvent *event) overridefinal
#define TTK_APP_NAME
Definition: ttkobject.h:25
QDomElement writeDomElement(QDomElement &element, const QString &node) const
voidpf void uLong size
Definition: ioapi.h:136
void setStyleSheet(const QString &style) const
MusicTTKFMRadioInformationWidget(QWidget *parent=nullptr)
MusicTTKFMRadioPlayWidget(QWidget *parent=nullptr)
Ui::MusicTTKFMRadioInformationWidget * m_ui
The class of the messagebox widget.
The class of the web music radio information widget.
void setVolume(int value)
QDomElement writeDomMultiElement(QDomElement &element, const QString &node, const TTKXmlNode &attrs) const
void setChannelInformation(const MusicFMChannel &channel)
int indexValid(QTreeWidgetItem *item) const
static void popup(const QString &text)
void setAlignment(Qt::Alignment alignment) const
static const QString ScrollBarStyle03
void createProcessingInstruction() const
QDomElement createRoot(const QString &node) const
voidpf uLong offset
Definition: ioapi.h:142
#define qAsConst
Definition: ttkqtglobal.h:53
static const QString ColorStyle02
Definition: musicuiobject.h:40
static const QString BackgroundStyle01
Background.
Definition: musicuiobject.h:77
The class of the fm channel item.
virtual bool writeBuffer(const MusicFMCategoryList &items) overridefinal
TTK_MODULE_EXPORT void adjustWidgetPosition(QWidget *widget)
static const QString PushButtonStyle04
Ui::MusicTTKFMRadioPlayWidget * m_ui
The class of the moving dialog base.
The class of the mplayer core.
Definition: inftrees.h:24
void radioItemChanged(QTreeWidgetItem *item, int column)
#define FMRADIO_PATH
#define TTK_DN_S2MS
Definition: ttkglobal.h:276
void save() const
The class of the web music radio widget.
static const QString ToolButtonStyle04
The class of the fm category item.
void setModuleMode(TTKUInt8 mode)
const char int mode
Definition: ioapi.h:135
void setMedia(Module type, const QString &data, int winId=-1)
virtual bool readBuffer(MusicFMCategoryList &items) overridefinal
#define TTK_DATA_ROLE
static qint64 formatDuration(const QString &time) noexcept
Definition: ttktime.cpp:123
The class of the moving widget base.