MythTV  master
musiccommon.cpp
Go to the documentation of this file.
1 // C++ includes
2 #include <cstdlib>
3 #include <iostream>
4 
5 // Qt includes
6 #include <QApplication>
7 #include <QLocale>
8 
9 // mythtv
11 #include <libmythbase/lcddevice.h>
13 #include <libmythbase/mythdate.h>
15 #include <libmythbase/mythrandom.h>
17 #include <libmythui/mythuibutton.h>
21 #include <libmythui/mythuiimage.h>
24 #include <libmythui/mythuitext.h>
26 #include <libmythui/mythuivideo.h>
27 
28 // MythMusic includes
29 #include "constants.h"
30 #include "decoder.h"
31 #include "editmetadata.h"
32 #include "lyricsview.h"
33 #include "mainvisual.h"
34 #include "musiccommon.h"
35 #include "musicdata.h"
36 #include "playlist.h"
37 #include "playlistcontainer.h"
38 #include "playlisteditorview.h"
39 #include "playlistview.h"
40 #include "search.h"
41 #include "searchview.h"
42 #include "smartplaylist.h"
43 #include "streamview.h"
44 #include "visualizerview.h"
45 
47  const QString &name)
48  : MythScreenType(parent, name),
49  m_parentScreen(parentScreen)
50 {
51  m_cycleVisualizer = gCoreContext->GetBoolSetting("VisualCycleOnSongChange", false);
52 
53  if (LCD *lcd = LCD::Get())
54  {
55  lcd->switchToTime();
56  lcd->setFunctionLEDs(FUNC_MUSIC, true);
57  }
58 }
59 
61 {
62  gPlayer->removeListener(this);
63 
64  if (m_mainvisual)
65  {
67  delete m_mainvisual;
68  m_mainvisual = nullptr;
69  }
70 
71  if (LCD *lcd = LCD::Get())
72  {
73  lcd->switchToTime();
74  lcd->setFunctionLEDs(FUNC_MUSIC, false);
75  }
76 }
77 
79 {
80  bool err = false;
81  UIUtilW::Assign(this, m_timeText, "time", &err);
82  UIUtilW::Assign(this, m_infoText, "info", &err);
83  UIUtilW::Assign(this, m_visualText, "visualizername", &err);
84  UIUtilW::Assign(this, m_noTracksText, "notracks", &err);
85 
86  UIUtilW::Assign(this, m_shuffleState, "shufflestate", &err);
87  UIUtilW::Assign(this, m_repeatState, "repeatstate", &err);
88  UIUtilW::Assign(this, m_movingTracksState, "movingtracksstate", &err);
89 
90  UIUtilW::Assign(this, m_ratingState, "ratingstate", &err);
91 
92  UIUtilW::Assign(this, m_trackProgress, "progress", &err);
93  UIUtilW::Assign(this, m_trackProgressText, "trackprogress", &err);
94  UIUtilW::Assign(this, m_trackSpeedText, "trackspeed", &err);
95  UIUtilW::Assign(this, m_trackState, "trackstate", &err);
96 
97  UIUtilW::Assign(this, m_volumeText, "volume", &err);
98  UIUtilW::Assign(this, m_muteState, "mutestate", &err);
99 
100  UIUtilW::Assign(this, m_playlistProgress, "playlistprogress", &err);
101 
102  UIUtilW::Assign(this, m_prevButton, "prev", &err);
103  UIUtilW::Assign(this, m_rewButton, "rew", &err);
104  UIUtilW::Assign(this, m_pauseButton, "pause", &err);
105  UIUtilW::Assign(this, m_playButton, "play", &err);
106  UIUtilW::Assign(this, m_stopButton, "stop", &err);
107  UIUtilW::Assign(this, m_ffButton, "ff", &err);
108  UIUtilW::Assign(this, m_nextButton, "next", &err);
109 
110  UIUtilW::Assign(this, m_coverartImage, "coverart", &err);
111 
112  UIUtilW::Assign(this, m_currentPlaylist, "currentplaylist", &err);
113  UIUtilW::Assign(this, m_playedTracksList, "playedtrackslist", &err);
114 
115  UIUtilW::Assign(this, m_visualizerVideo, "visualizer", &err);
116 
117  if (m_prevButton)
119 
120  if (m_rewButton)
122 
123  if (m_pauseButton)
124  {
125  m_pauseButton->SetLockable(true);
127  }
128 
129  if (m_playButton)
130  {
131  m_playButton->SetLockable(true);
133  }
134 
135  if (m_stopButton)
136  {
137  m_stopButton->SetLockable(true);
139  }
140 
141  if (m_ffButton)
143 
144  if (m_nextButton)
146 
147  if (m_currentPlaylist)
148  {
153 
154  m_currentPlaylist->SetSearchFields("**search**");
155  }
156 
157  init();
158 
159  return err;
160 }
161 
163 {
164  gPlayer->addListener(this);
165 
166  if (startPlayback)
167  {
168  if (!gPlayer->isPlaying())
169  {
170  if (m_currentView == MV_VISUALIZER ||
171  m_currentView == MV_VISUALIZERINFO) // keep playmode
173  else if (m_currentView == MV_RADIO)
177  else
179 
181  }
182  else
183  {
184  // if we are playing but we are switching to a view from a different playmode
185  // we need to restart playback in the new mode
187  {
188  // these views can be used in both play modes
189  }
191  {
192  gPlayer->stop(true);
193 
196  else
198 
200  }
202  {
203  gPlayer->stop(true);
206  }
207  }
208  }
209 
211 
213  if (curMeta)
214  updateTrackInfo(curMeta);
215 
217 
218  if (m_currentPlaylist)
220 
221  if (m_visualizerVideo)
222  {
224 
226 
227  m_fullscreenBlank = false;
228 
229  m_randomVisualizer = gCoreContext->GetBoolSetting("VisualRandomize", false);
230 
232 
233  // sanity check
234  if (m_currentVisual >= static_cast<uint>(m_visualModes.count()))
235  {
236  LOG(VB_GENERAL, LOG_ERR, QString("MusicCommon: Got a bad saved visualizer: %1").arg(m_currentVisual));
237  m_currentVisual = 0;
238  }
239 
241 
242  if (gPlayer->isPlaying())
243  startVisualizer();
244  }
245 
246  m_controlVolume = gCoreContext->GetBoolSetting("MythControlsVolume", false);
247  updateVolume();
248 
251 
252  if (m_stopButton)
254  if (m_playButton)
256  if (m_pauseButton)
258  if (m_trackState)
259  {
260  if (gPlayer->isPlaying())
261  m_trackState->DisplayState("playing");
262  else if (gPlayer->isPaused())
263  m_trackState->DisplayState("paused");
264  else
265  m_trackState->DisplayState("stopped");
266 
267  }
268 
271 
275 
276  if (m_playlistProgress)
277  {
280  }
281 
283 
285 }
286 
288 {
289  if (m_repeatState)
290  {
291  switch (gPlayer->getRepeatMode())
292  {
294  m_repeatState->DisplayState("off");
295  if (class LCD *lcd = LCD::Get())
296  lcd->setMusicRepeat (LCD::MUSIC_REPEAT_NONE);
297  break;
299  m_repeatState->DisplayState("track");
300  if (class LCD *lcd = LCD::Get())
301  lcd->setMusicRepeat (LCD::MUSIC_REPEAT_TRACK);
302  break;
304  m_repeatState->DisplayState("all");
305  if (class LCD *lcd = LCD::Get())
306  lcd->setMusicRepeat (LCD::MUSIC_REPEAT_ALL);
307  break;
308  default:
309  m_repeatState->DisplayState("off");
310  if (class LCD *lcd = LCD::Get())
311  lcd->setMusicRepeat (LCD::MUSIC_REPEAT_NONE);
312  break;
313  }
314  }
315 
316  // need this to update the next track info
318  if (curMeta)
319  updateTrackInfo(curMeta);
320 }
321 
322 void MusicCommon::updateShuffleMode(bool updateUIList)
323 {
324  if (m_shuffleState)
325  {
326  switch (gPlayer->getShuffleMode())
327  {
330  if (class LCD *lcd = LCD::Get())
331  lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_NONE);
332  break;
334  m_shuffleState->DisplayState("random");
335  if (class LCD *lcd = LCD::Get())
336  lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_RAND);
337  break;
339  m_shuffleState->DisplayState("intelligent");
340  if (class LCD *lcd = LCD::Get())
341  lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_SMART);
342  break;
344  m_shuffleState->DisplayState("album");
345  if (class LCD *lcd = LCD::Get())
346  lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_ALBUM);
347  break;
349  m_shuffleState->DisplayState("artist");
350  if (class LCD *lcd = LCD::Get())
351  lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_ARTIST);
352  break;
353  default:
355  if (class LCD *lcd = LCD::Get())
356  lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_NONE);
357  break;
358  }
359  }
360 
361  if (updateUIList)
362  {
364 
369 
370  // need this to update the next track info
372  if (curMeta)
373  updateTrackInfo(curMeta);
374  }
375 }
376 
378 {
379  // can we switch to this view from the current view?
380  switch (m_currentView)
381  {
382  case MV_PLAYLIST:
383  {
384  if (view != MV_PLAYLISTEDITORTREE && view != MV_PLAYLISTEDITORGALLERY &&
385  view != MV_SEARCH && view != MV_VISUALIZER && view != MV_LYRICS)
386  return;
387  break;
388  }
389 
391  {
392  if (view != MV_PLAYLISTEDITORGALLERY && view != MV_SEARCH && view != MV_VISUALIZER && view != MV_LYRICS)
393  return;
394  break;
395  }
396 
398  {
399  if (view != MV_PLAYLISTEDITORTREE && view != MV_SEARCH && view != MV_VISUALIZER && view != MV_LYRICS)
400  return;
401  break;
402  }
403 
404  case MV_SEARCH:
405  {
406  if (view != MV_VISUALIZER && view != MV_LYRICS)
407  return;
408  break;
409  }
410 
411  case MV_VISUALIZER:
412  {
413  return;
414  }
415 
416  case MV_LYRICS:
417  {
418  if (view != MV_VISUALIZER && view != MV_SEARCH)
419  return;
420  break;
421  }
422 
423  case MV_RADIO:
424  {
425  if (view != MV_VISUALIZER && view != MV_LYRICS)
426  return;
427  break;
428  }
429 
430  default:
431  return;
432  }
433 
435 
436  stopVisualizer();
437 
438  if (m_mainvisual)
439  {
440  delete m_mainvisual;
441  m_mainvisual = nullptr;
442  }
443 
444  gPlayer->removeListener(this);
445  gPlayer->setAllowRestorePos(false);
446 
447  switch (view)
448  {
449  case MV_PLAYLIST:
450  {
451  auto *plview = new PlaylistView(mainStack, this);
452 
453  if (plview->Create())
454  {
455  mainStack->AddScreen(plview);
456  connect(plview, &MythScreenType::Exiting, this, &MusicCommon::viewExited);
457  }
458  else
459  {
460  delete plview;
461  }
462 
463  break;
464  }
465 
467  {
468  // if we are switching playlist editor views save and restore
469  // the current position in the tree
470  bool restorePos = (m_currentView == MV_PLAYLISTEDITORGALLERY);
471  auto *oldView = qobject_cast<PlaylistEditorView *>(this);
472  if (oldView)
473  oldView->saveTreePosition();
474 
475  MythScreenType *parentScreen = (oldView != nullptr ? m_parentScreen : this);
476 
477  auto *pleview = new PlaylistEditorView(mainStack, parentScreen, "tree", restorePos);
478 
479  if (pleview->Create())
480  {
481  mainStack->AddScreen(pleview);
482  connect(pleview, &MythScreenType::Exiting, this, &MusicCommon::viewExited);
483  }
484  else
485  {
486  delete pleview;
487  }
488 
489  if (oldView)
490  Close();
491 
492  break;
493  }
494 
496  {
497  // if we are switching playlist editor views save and restore
498  // the current position in the tree
499  bool restorePos = (m_currentView == MV_PLAYLISTEDITORTREE);
500  auto *oldView = qobject_cast<PlaylistEditorView *>(this);
501  if (oldView)
502  oldView->saveTreePosition();
503 
504  MythScreenType *parentScreen = (oldView != nullptr ? m_parentScreen : this);
505 
506  auto *pleview = new PlaylistEditorView(mainStack, parentScreen, "gallery", restorePos);
507 
508  if (pleview->Create())
509  {
510  mainStack->AddScreen(pleview);
511  connect(pleview, &MythScreenType::Exiting, this, &MusicCommon::viewExited);
512  }
513  else
514  {
515  delete pleview;
516  }
517 
518  if (oldView)
519  Close();
520 
521  break;
522  }
523 
524  case MV_SEARCH:
525  {
526  auto *sview = new SearchView(mainStack, this);
527 
528  if (sview->Create())
529  {
530  mainStack->AddScreen(sview);
531  connect(sview, &MythScreenType::Exiting, this, &MusicCommon::viewExited);
532  }
533  else
534  {
535  delete sview;
536  }
537 
538  break;
539  }
540 
541  case MV_VISUALIZER:
542  {
543  auto *vview = new VisualizerView(mainStack, this);
544 
545  if (vview->Create())
546  {
547  mainStack->AddScreen(vview);
548  connect(vview, &MythScreenType::Exiting, this, &MusicCommon::viewExited);
549  }
550  else
551  {
552  delete vview;
553  }
554 
555  break;
556  }
557 
558  case MV_LYRICS:
559  {
560  auto *lview = new LyricsView(mainStack, this);
561 
562  if (lview->Create())
563  {
564  mainStack->AddScreen(lview);
565  connect(lview, &MythScreenType::Exiting, this, &MusicCommon::viewExited);
566  }
567  else
568  {
569  delete lview;
570  }
571 
572  break;
573  }
574 
575  default:
576  break;
577  }
578 
580 }
581 
583 {
584  init(false);
585 }
586 
587 bool MusicCommon::keyPressEvent(QKeyEvent *e)
588 {
589  bool handled = false;
590 
591  // if there is a pending jump point pass the key press to the default handler
592  if (GetMythMainWindow()->IsExitingToMain())
593  {
595 
596  // do we need to stop playing?
597  if (gPlayer->isPlaying() && gCoreContext->GetSetting("MusicJumpPointAction", "stop") == "stop")
598  gPlayer->stop(true);
599 
601  }
602 
603  QStringList actions;
604  handled = GetMythMainWindow()->TranslateKeyPress("Music", e, actions, true);
605 
606  for (int i = 0; i < actions.size() && !handled; i++)
607  {
608  const QString& action = actions[i];
609  handled = true;
610 
611  // if we are currently moving an item,
612  // we only accept UP/DOWN/SELECT/ESCAPE
614  {
616  if (!item)
617  return false;
618 
619  if (action == "SELECT" || action == "ESCAPE")
620  {
621  m_movingTrack = false;
622  item->DisplayState("off", "movestate");
623  }
624  else if (action == "UP")
625  {
627  item->MoveUpDown(true);
634  }
635  else if (action == "DOWN")
636  {
638  item->MoveUpDown(false);
645  }
646 
647  return true;
648  }
649 
650  if (action == "ESCAPE")
651  {
652  // if we was started from another music view screen return to it
653  if (m_parentScreen)
654  {
655  handled = false;
656  }
657  else
658  {
659  // this is the top music view screen so prompt to continue playing
660  QString exit_action = gCoreContext->GetSetting("MusicExitAction", "prompt");
661 
662  if (!gPlayer->isPlaying())
663  {
665  stopAll();
666  Close();
667  }
668  else
669  {
670  if (exit_action == "stop")
671  {
673  stopAll();
674  Close();
675  }
676  else if (exit_action == "play")
677  {
678  Close();
679  }
680  else
681  {
682  showExitMenu();
683  }
684  }
685  }
686  }
687  else if (action == "THMBUP")
688  {
689  changeRating(true);
690  }
691  else if (action == "THMBDOWN")
692  {
693  changeRating(false);
694  }
695  else if (action == "NEXTTRACK")
696  {
697  if (m_nextButton)
698  m_nextButton->Push();
699  else
700  next();
701  }
702  else if (action == "PREVTRACK")
703  {
704  if (m_prevButton)
705  m_prevButton->Push();
706  else
707  previous();
708  }
709  else if (action == "FFWD")
710  {
712  {
713  if (m_ffButton)
714  m_ffButton->Push();
715  else
716  seekforward();
717  }
718  }
719  else if (action == "RWND")
720  {
722  {
723  if (m_rewButton)
724  m_rewButton->Push();
725  else
726  seekback();
727  }
728  }
729  else if (action == "PAUSE")
730  {
732  {
733  // ignore if we are already playing a radio stream
734  }
735  else if (gPlayer->isPlaying() || (gPlayer->getOutput() && gPlayer->getOutput()->IsPaused()))
736  {
737  // if we are playing or are paused PAUSE will toggle the pause state
738  if (m_pauseButton)
739  m_pauseButton->Push();
740  else
741  pause();
742  }
743  else
744  {
745  // not playing or paused so PAUSE acts the same as PLAY
746  if (m_playButton)
747  m_playButton->Push();
748  else
749  play();
750  }
751  }
752  else if (action == "PLAY")
753  {
754  if (m_playButton)
755  m_playButton->Push();
756  else
757  play();
758  }
759  else if (action == "STOP")
760  {
761  if (m_stopButton)
762  m_stopButton->Push();
763  else
764  stop();
765  m_currentTime = 0s;
766  }
767  else if (action == "CYCLEVIS")
768  {
769  cycleVisualizer();
770  }
771  else if (action == "BLANKSCR")
772  {
773  // change to the blank visualizer
774  if (m_mainvisual)
775  switchVisualizer("Blank");
776 
777  // switch to the full screen visualiser view
780  }
781  else if (action == "VOLUMEDOWN")
782  {
783  changeVolume(false);
784  }
785  else if (action == "VOLUMEUP")
786  {
787  changeVolume(true);
788  }
789  else if (action == "SPEEDDOWN")
790  {
791  changeSpeed(false);
792  }
793  else if (action == "SPEEDUP")
794  {
795  changeSpeed(true);
796  }
797  else if (action == "MUTE")
798  {
799  toggleMute();
800  }
801  else if (action == "TOGGLEUPMIX")
802  {
803  toggleUpmix();
804  }
805  else if (action == "INFO" || action == "EDIT")
806  {
808  {
810  {
811  auto *mdata = m_currentPlaylist->GetItemCurrent()->GetData().value<MusicMetadata*>();
812  if (mdata)
813  {
814  if (action == "INFO")
815  showTrackInfo(mdata);
816  else
817  editTrackInfo(mdata);
818  }
819  }
820  }
821  else
822  {
823  if (action == "INFO")
825  else
827  }
828  }
829  else if (action == "DELETE" && m_currentPlaylist && GetFocusWidget() == m_currentPlaylist)
830  {
832  if (item)
833  {
834  auto *mdata = item->GetData().value<MusicMetadata*>();
835  if (mdata)
836  gPlayer->removeTrack(mdata->ID());
837  }
838  }
839  else if (action == "MENU")
840  {
841  ShowMenu();
842  }
843  else if (action == "REFRESH")
844  {
845  if (m_currentPlaylist)
847  }
848  else if (action == "MARK")
849  {
850  if (!m_moveTrackMode)
851  {
852  m_moveTrackMode = true;
853  m_movingTrack = false;
854 
857  }
858  else
859  {
860  m_moveTrackMode = false;
861 
863  {
865  if (item)
866  item->DisplayState("off", "movestate");
867 
868  m_movingTrack = false;
869  }
870 
873  }
874  }
875  else if (action == "SWITCHTOPLAYLIST" && m_currentView != MV_PLAYLIST)
876  {
878  }
879  else if (action == "SWITCHTOPLAYLISTEDITORTREE" && m_currentView != MV_PLAYLISTEDITORTREE)
880  {
882  }
883  else if (action == "SWITCHTOPLAYLISTEDITORGALLERY" && m_currentView != MV_PLAYLISTEDITORGALLERY)
884  {
886  }
887  else if (action == "SWITCHTOSEARCH" && m_currentView != MV_SEARCH)
888  {
890  }
891  else if (action == "SWITCHTOVISUALISER" && m_currentView != MV_VISUALIZER)
892  {
894  }
895  else if (action == "SWITCHTORADIO" && m_currentView != MV_RADIO)
896  {
898  }
899  else if (action == "TOGGLESHUFFLE")
900  {
902  updateShuffleMode(true);
903  }
904  else if (action == "TOGGLEREPEAT")
905  {
908  }
909  else
910  {
911  handled = false;
912  }
913  }
914 
915  if (!handled && MythScreenType::keyPressEvent(e))
916  handled = true;
917  return handled;
918 }
919 
920 void MusicCommon::changeVolume(bool up) const
921 {
923  {
924  if (up)
925  gPlayer->incVolume();
926  else
927  gPlayer->decVolume();
928  showVolume();
929  }
930 }
931 
933 {
935  {
936  if (up)
937  gPlayer->incSpeed();
938  else
939  gPlayer->decSpeed();
940  showSpeed(true);
941  updatePlaylistStats(); // update trackspeed and map for templates
942  }
943 }
944 
946 {
947  if (m_controlVolume)
948  {
949  gPlayer->toggleMute();
950  showVolume();
951  }
952 }
953 
955 {
956  if (gPlayer->getOutput())
958 }
959 
961 {
962  if (!m_trackProgress)
963  return;
964 
966  {
967  // radio mode so show the buffer fill level since we don't know the track length
968  int available = 0;
969  int maxSize = 0;
970  gPlayer->getBufferStatus(&available, &maxSize);
971 
972  if (m_infoText)
973  {
974  QString status = QString("%1%").arg((int)(100.0 / ((double)maxSize / (double)available)));
975  m_infoText->SetText(status);
976  }
977 
978  if (m_trackProgress)
979  {
980  m_trackProgress->SetTotal(maxSize);
981  m_trackProgress->SetUsed(available);
982  }
983  }
984  else
985  {
986  // show the track played time
987  int percentplayed = 1;
988  if (m_maxTime > 0s)
989  percentplayed = m_currentTime * 100 / m_maxTime;
991  m_trackProgress->SetUsed(percentplayed);
992  }
993 }
994 
996 {
997  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
998 
999  auto *vol = new MythMusicVolumeDialog(popupStack, "volumepopup");
1000 
1001  if (!vol->Create())
1002  {
1003  delete vol;
1004  return;
1005  }
1006 
1007  popupStack->AddScreen(vol);
1008 }
1009 
1010 void MusicCommon::showSpeed([[maybe_unused]] bool show)
1011 {
1012 }
1013 
1014 void MusicCommon::switchVisualizer(const QString &visual)
1015 {
1016  switchVisualizer(m_visualModes.indexOf(visual));
1017 }
1018 
1020 {
1021  if (!m_mainvisual)
1022  return;
1023 
1024  if (visual < 0 || visual > m_visualModes.count() - 1)
1025  visual = 0;
1026 
1027  m_currentVisual = visual;
1028 
1030 
1031  if (m_visualText)
1033 }
1034 
1036 {
1037  if (!m_mainvisual)
1038  return;
1039 
1040  // Only change the visualizer if there is more than 1 visualizer
1041  // and the user currently has a visualizer active
1042  if (m_visualModes.count() > 1)
1043  {
1044  if (m_randomVisualizer)
1045  {
1046  unsigned int next_visualizer = 0;
1047 
1048  //Find a visual thats not like the previous visual
1049  do
1050  next_visualizer = MythRandom(0, m_visualModes.count() - 1);
1051  while (next_visualizer == m_currentVisual);
1052  m_currentVisual = next_visualizer;
1053  }
1054  else
1055  {
1056  //Change to the next selected visual
1057  m_currentVisual = (m_currentVisual + 1) % m_visualModes.count();
1058  }
1059 
1060  //Change to the new visualizer
1062  }
1063 }
1064 
1066 {
1068  return;
1069 
1071 }
1072 
1074 {
1076  return;
1077 
1079 }
1080 
1082 {
1083  LCD *lcd = LCD::Get();
1084  if (!lcd || !mdata)
1085  return;
1086 
1087  // Set the Artist and Tract on the LCD
1088  lcd->switchToMusic(mdata->Artist(),
1089  mdata->Album(),
1090  mdata->Title());
1091 }
1092 
1094 {
1095  if (LCD *lcd = LCD::Get())
1096  {
1097  lcd->switchToTime();
1098  }
1099 
1100  stopVisualizer();
1101 
1102  gPlayer->stop(true);
1103 }
1104 
1106 {
1107  gPlayer->play();
1108 }
1109 
1111 {
1112  gPlayer->pause();
1113 }
1114 
1116 {
1117  gPlayer->stop();
1118 
1119  if (m_timeText)
1121  if (m_infoText)
1122  m_infoText->Reset();
1123 }
1124 
1126 {
1127  if (m_cycleVisualizer)
1128  cycleVisualizer();
1129 
1130 
1131  gPlayer->next();
1132 }
1133 
1135 {
1136  if (m_cycleVisualizer)
1137  cycleVisualizer();
1138 
1139  gPlayer->previous();
1140 }
1141 
1143 {
1144  std::chrono::seconds nextTime = m_currentTime + 5s;
1145  nextTime = std::clamp(nextTime, 0s, m_maxTime);
1146  seek(nextTime);
1147 }
1148 
1150 {
1151  // I don't know why, but seeking before 00:05 fails. Repeated
1152  // rewind under 00:05 can hold time < 5s while the music plays.
1153  // Time starts incrementing from zero but is now several seconds
1154  // behind. Finishing a track after this records a truncated
1155  // length. We can workaround this by limiting rewind to 1s.
1156  std::chrono::seconds nextTime = m_currentTime - 5s;
1157  nextTime = std::clamp(nextTime, 1s, m_maxTime); // #787
1158  seek(nextTime);
1159 }
1160 
1161 void MusicCommon::seek(std::chrono::seconds pos)
1162 {
1163  if (gPlayer->getOutput())
1164  {
1165  Decoder *decoder = gPlayer->getDecoder();
1166  if (decoder && decoder->isRunning())
1167  {
1168  decoder->lock();
1169  decoder->seek(pos.count());
1170 
1171  if (m_mainvisual)
1172  {
1173  m_mainvisual->mutex()->lock();
1174  m_mainvisual->prepare();
1175  m_mainvisual->mutex()->unlock();
1176  }
1177 
1178  decoder->unlock();
1179  }
1180 
1181  gPlayer->getOutput()->SetTimecode(pos);
1182 
1183  if (!gPlayer->isPlaying())
1184  {
1185  m_currentTime = pos;
1186  if (m_timeText)
1188 
1190 
1191  if (LCD *lcd = LCD::Get())
1192  {
1193  float percent_heard = m_maxTime <= 0s ? 0.0F : ((float)pos.count() /
1194  (float)m_maxTime.count());
1195 
1196  QString lcd_time_string = getTimeString(pos, m_maxTime);
1197 
1198  // if the string is longer than the LCD width, remove all spaces
1199  if (lcd_time_string.length() > lcd->getLCDWidth())
1200  lcd_time_string.remove(' ');
1201 
1202  lcd->setMusicProgress(lcd_time_string, percent_heard);
1203  }
1204  }
1205  }
1206 }
1207 
1208 void MusicCommon::changeRating(bool increase)
1209 {
1211  return;
1212 
1213  // Rationale here is that if you can't get visual feedback on ratings
1214  // adjustments, you probably should not be changing them
1215  // TODO: should check if the rating is visible in the playlist buttontlist
1216  //if (!m_ratingState)
1217  // return;
1218 
1220  if (!curMeta)
1221  return;
1222 
1223 
1224  if (increase)
1225  curMeta->incRating();
1226  else
1227  curMeta->decRating();
1228 
1229  gPlayer->sendTrackStatsChangedEvent(curMeta->ID());
1230 }
1231 
1232 void MusicCommon::customEvent(QEvent *event)
1233 {
1234  QString statusString;
1235 
1236  if (event->type() == OutputEvent::kPlaying)
1237  {
1239  if (curMeta)
1240  updateTrackInfo(curMeta);
1241 
1242  statusString = tr("Playing stream.");
1243  if (gPlayer->isPlaying())
1244  {
1245  if (m_stopButton)
1246  m_stopButton->SetLocked(false);
1247  if (m_playButton)
1248  m_playButton->SetLocked(true);
1249  if (m_pauseButton)
1250  m_pauseButton->SetLocked(false);
1251  if (m_trackState)
1252  m_trackState->DisplayState("playing");
1253 
1254  if (m_currentPlaylist)
1255  {
1257  if (item)
1258  {
1259  item->SetFontState("running");
1260  item->DisplayState("playing", "playstate");
1261  }
1262  }
1263 
1264  startVisualizer();
1265 
1266  updateVolume();
1267  }
1268  }
1269  else if (event->type() == OutputEvent::kBuffering)
1270  {
1271  statusString = tr("Buffering stream.");
1272  }
1273  else if (event->type() == OutputEvent::kPaused)
1274  {
1275  statusString = tr("Stream paused.");
1276 
1277  if (m_stopButton)
1278  m_stopButton->SetLocked(false);
1279  if (m_playButton)
1280  m_playButton->SetLocked(false);
1281  if (m_pauseButton)
1282  m_pauseButton->SetLocked(true);
1283  if (m_trackState)
1284  m_trackState->DisplayState("paused");
1285 
1286  if (m_currentPlaylist)
1287  {
1289  if (item)
1290  {
1291  item->SetFontState("idle");
1292  item->DisplayState("paused", "playstate");
1293  }
1294  }
1295  }
1296  else if (event->type() == OutputEvent::kInfo)
1297  {
1298 
1299  auto *oe = dynamic_cast<OutputEvent *>(event);
1300 
1301  if (!oe)
1302  return;
1303 
1304  std::chrono::seconds rs = 0s;
1306 
1308  {
1309  if (curMeta)
1310  m_currentTime = rs = duration_cast<std::chrono::seconds>(curMeta->Length());
1311  else
1312  m_currentTime = 0s;
1313  }
1314  else
1315  {
1316  m_currentTime = rs = oe->elapsedSeconds();
1317  }
1318 
1319  QString time_string = getTimeString(rs, m_maxTime);
1320 
1322 
1323  if (curMeta)
1324  {
1325  if (LCD *lcd = LCD::Get())
1326  {
1327  float percent_heard = m_maxTime <= 0s ?
1328  0.0F:((float)rs.count() / (float)curMeta->Length().count()) * 1000.0F;
1329 
1330  QString lcd_time_string = time_string;
1331 
1332  // if the string is longer than the LCD width, remove all spaces
1333  if (time_string.length() > lcd->getLCDWidth())
1334  lcd_time_string.remove(' ');
1335 
1336  lcd->setMusicProgress(lcd_time_string, percent_heard);
1337  }
1338  }
1339 
1340  QString info_string;
1341 
1342  // Hack around for cd bitrates
1343  if (oe->bitrate() < 2000)
1344  {
1345  info_string = QString("%1 "+tr("kbps")+ " %2 "+ tr("kHz")+ " %3 "+ tr("ch"))
1346  .arg(oe->bitrate())
1347  .arg(static_cast<double>(oe->frequency()) / 1000.0,0,'f',1,QChar('0'))
1348  .arg(oe->channels() > 1 ? "2" : "1");
1349  }
1350  else
1351  {
1352  info_string = QString("%1 "+ tr("kHz")+ " %2 "+ tr("ch"))
1353  .arg(static_cast<double>(oe->frequency()) / 1000.0,0,'f',1,QChar('0'))
1354  .arg(oe->channels() > 1 ? "2" : "1");
1355  }
1356 
1357  if (curMeta)
1358  {
1359  if (m_timeText)
1360  m_timeText->SetText(time_string);
1361  if (m_infoText)
1362  m_infoText->SetText(info_string);
1363  }
1364 
1365  // TODO only need to update the playlist times here
1367  }
1368  else if (event->type() == OutputEvent::kStopped)
1369  {
1370  statusString = tr("Stream stopped.");
1371  if (m_stopButton)
1372  m_stopButton->SetLocked(true);
1373  if (m_playButton)
1374  m_playButton->SetLocked(false);
1375  if (m_pauseButton)
1376  m_pauseButton->SetLocked(false);
1377  if (m_trackState)
1378  m_trackState->DisplayState("stopped");
1379 
1380  if (m_currentPlaylist)
1381  {
1383  if (item)
1384  {
1385  item->SetFontState("normal");
1386  item->DisplayState("stopped", "playstate");
1387  }
1388  }
1389 
1390  stopVisualizer();
1391  }
1392  else if (event->type() == DialogCompletionEvent::kEventType)
1393  {
1394  auto *dce = dynamic_cast<DialogCompletionEvent*>(event);
1395 
1396  // make sure the user didn't ESCAPE out of the menu
1397  if ((dce == nullptr) || (dce->GetResult() < 0))
1398  return;
1399 
1400  QString resultid = dce->GetId();
1401  QString resulttext = dce->GetResultText();
1402 
1403  if (resultid == "mainmenu")
1404  {
1405  if (resulttext == tr("Fullscreen Visualizer"))
1407  else if (resulttext == tr("Playlist Editor") ||
1408  resulttext == tr("Browse Music Library"))
1409  {
1410  if (gCoreContext->GetSetting("MusicPlaylistEditorView", "tree") == "tree")
1412  else
1414  }
1415  else if (resulttext == tr("Search for Music"))
1416  {
1418  }
1419  else if (resulttext == tr("Switch To Gallery View"))
1420  {
1422  }
1423  else if (resulttext == tr("Switch To Tree View"))
1424  {
1426  }
1427  else if (resulttext == tr("Lyrics"))
1428  {
1430  }
1431  }
1432  else if (resultid == "submenu")
1433  {
1434  if (resulttext == tr("Search List..."))
1435  searchButtonList();
1436  }
1437  else if (resultid == "playlistmenu")
1438  {
1439  if (resulttext == tr("Sync List With Current Track"))
1440  {
1442  }
1443  else if (resulttext == tr("Remove Selected Track"))
1444  {
1446  if (item)
1447  {
1448  auto *mdata = item->GetData().value<MusicMetadata*>();
1449  if (mdata)
1450  gPlayer->removeTrack(mdata->ID());
1451  }
1452  }
1453  else if (resulttext == tr("Remove All Tracks"))
1454  {
1455  if (gPlayer->getCurrentPlaylist())
1456  {
1458  gPlayer->activePlaylistChanged(-1, true);
1459  }
1460  }
1461  else if (resulttext == tr("Save To New Playlist"))
1462  {
1463  QString message = tr("Enter new playlist name");
1464 
1465  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
1466 
1467  auto *inputdialog = new MythTextInputDialog(popupStack, message);
1468 
1469  if (inputdialog->Create())
1470  {
1471  inputdialog->SetReturnEvent(this, "addplaylist");
1472  popupStack->AddScreen(inputdialog);
1473  }
1474  else
1475  {
1476  delete inputdialog;
1477  }
1478  }
1479  else if (resulttext == tr("Save To Existing Playlist"))
1480  {
1481  QString message = tr("Select the playlist to save to");
1482  QStringList playlists = gMusicData->m_all_playlists->getPlaylistNames();
1483 
1484  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
1485 
1486  auto *searchdialog = new MythUISearchDialog(popupStack, message, playlists);
1487 
1488  if (searchdialog->Create())
1489  {
1490  searchdialog->SetReturnEvent(this, "updateplaylist");
1491  popupStack->AddScreen(searchdialog);
1492  }
1493  }
1494  else if (resulttext == tr("Switch To Move Mode"))
1495  {
1496  m_moveTrackMode = true;
1497  m_movingTrack = false;
1498 
1499  if (m_movingTracksState)
1501  }
1502  else if (resulttext == tr("Switch To Select Mode"))
1503  {
1504  m_moveTrackMode = false;
1505 
1507  {
1509  if (item)
1510  item->DisplayState("off", "movestate");
1511 
1512  m_movingTrack = false;
1513  }
1514 
1515  if (m_movingTracksState)
1517  }
1518  }
1519  else if (resultid == "repeatmenu")
1520  {
1521  int mode = dce->GetData().toInt();
1523  updateRepeatMode();
1524  }
1525  else if (resultid == "shufflemenu")
1526  {
1527  int mode = dce->GetData().toInt();
1529  updateShuffleMode(true);
1530  }
1531  else if (resultid == "exitmenu")
1532  {
1533  if (resulttext == tr("No - Exit, Stop Playing"))
1534  {
1535  gPlayer->savePosition();
1536  stopAll();
1537  Close();
1538  }
1539  else if (resulttext == tr("Yes - Exit, Continue Playing"))
1540  {
1541  Close();
1542  }
1543  }
1544  else if (resultid == "playermenu")
1545  {
1546  if (resulttext == tr("Change Volume"))
1547  showVolume();
1548  else if (resulttext == tr("Mute"))
1549  toggleMute();
1550  else if (resulttext == tr("Previous Track"))
1551  previous();
1552  else if (resulttext == tr("Next Track"))
1553  next();
1554  else if (resulttext == tr("Jump Back"))
1555  seekback();
1556  else if (resulttext == tr("Jump Forward"))
1557  seekforward();
1558  else if (resulttext == tr("Play"))
1559  play();
1560  else if (resulttext == tr("Stop"))
1561  stop();
1562  else if (resulttext == tr("Pause"))
1563  pause();
1564  }
1565  else if (resultid == "quickplaylistmenu")
1566  {
1567  if (resulttext == tr("All Tracks"))
1568  allTracks();
1569  else if (resulttext == tr("From CD"))
1570  fromCD();
1571  else if (resulttext == tr("Tracks By Current Artist"))
1572  byArtist();
1573  else if (resulttext == tr("Tracks From Current Genre"))
1574  byGenre();
1575  else if (resulttext == tr("Tracks From Current Album"))
1576  byAlbum();
1577  else if (resulttext == tr("Tracks From Current Year"))
1578  byYear();
1579  else if (resulttext == tr("Tracks With Same Title"))
1580  byTitle();
1581  }
1582  else if (resultid == "playlistoptionsmenu")
1583  {
1584  if (resulttext == tr("Replace Tracks"))
1585  {
1587  doUpdatePlaylist();
1588  }
1589  else if (resulttext == tr("Add Tracks"))
1590  {
1592  doUpdatePlaylist();
1593  }
1594  else if (resulttext == tr("Play Now"))
1595  { // cancel shuffles and repeats to play only this now
1599  updateRepeatMode();
1602  doUpdatePlaylist();
1603  }
1604  else if (resulttext == tr("Prefer Play Now"))
1605  {
1607  }
1608  else if (resulttext == tr("Prefer Add Tracks"))
1609  {
1610  MusicPlayer::setPlayNow(false);
1611  }
1612  }
1613  else if (resultid == "visualizermenu")
1614  {
1615  if (dce->GetResult() >= 0)
1616  {
1617  m_currentVisual = dce->GetData().toInt();
1618 
1619  //Change to the new visualizer
1621  }
1622  }
1623  else if (resultid == "addplaylist")
1624  {
1626  Playlist *playlist = gMusicData->m_all_playlists->getPlaylist(resulttext);
1627  gPlayer->playlistChanged(playlist->getID());
1628  }
1629  else if (resultid == "updateplaylist")
1630  {
1631  if (gPlayer->getCurrentPlaylist())
1632  {
1633  Playlist *playlist = gMusicData->m_all_playlists->getPlaylist(resulttext);
1634  QString songList = gPlayer->getCurrentPlaylist()->toRawSonglist();
1635  playlist->removeAllTracks();
1636  playlist->fillSongsFromSonglist(songList);
1637  playlist->changed();
1638  gPlayer->playlistChanged(playlist->getID());
1639  }
1640  }
1641  }
1642  else if (event->type() == MusicPlayerEvent::kTrackChangeEvent)
1643  {
1644  auto *mpe = dynamic_cast<MusicPlayerEvent *>(event);
1645 
1646  if (!mpe)
1647  return;
1648 
1649  int trackNo = mpe->m_trackID;
1650 
1651  if (m_currentPlaylist)
1652  {
1653  if (m_currentTrack >= 0 && m_currentTrack < m_currentPlaylist->GetCount())
1654  {
1656  if (item)
1657  {
1658  item->SetFontState("normal");
1659  item->DisplayState("default", "playstate");
1660  }
1661  }
1662 
1663  if (trackNo >= 0 && trackNo < m_currentPlaylist->GetCount())
1664  {
1667 
1669  if (item)
1670  {
1671  item->SetFontState("running");
1672  item->DisplayState("playing", "playstate");
1673  }
1674  }
1675  }
1676 
1677  m_currentTrack = trackNo;
1678 
1679  if (gPlayer->getCurrentPlaylist())
1682  if (m_playlistProgress)
1683  {
1686  }
1687 
1690  }
1691  else if (event->type() == MusicPlayerEvent::kVolumeChangeEvent)
1692  {
1693  updateVolume();
1694  }
1695  else if (event->type() == MusicPlayerEvent::kTrackRemovedEvent)
1696  {
1697  auto *mpe = dynamic_cast<MusicPlayerEvent *>(event);
1698 
1699  if (!mpe)
1700  return;
1701 
1702  int trackID = mpe->m_trackID;
1703 
1704  if (m_currentPlaylist)
1705  {
1706  // find and remove the list item for the removed track
1707  for (int x = 0; x < m_currentPlaylist->GetCount(); x++)
1708  {
1710  auto *mdata = item->GetData().value<MusicMetadata*>();
1711  if (mdata && mdata->ID() == (MusicMetadata::IdType) trackID)
1712  {
1714  x -= 1; // remove all entries, or:
1715  // break; // remove only first entry
1716  }
1717  }
1718  }
1719 
1721 
1722  // if we have just removed the playing track from the playlist
1723  // move to the next track
1724  if (gPlayer->getCurrentMetadata())
1725  {
1726  if (gPlayer->getCurrentMetadata()->ID() == (MusicMetadata::IdType) trackID)
1727  gPlayer->next();
1728  }
1729 
1730  if (gPlayer->getCurrentPlaylist())
1735 
1738  }
1739  else if (event->type() == MusicPlayerEvent::kTrackAddedEvent)
1740  {
1741  auto *mpe = dynamic_cast<MusicPlayerEvent *>(event);
1742 
1743  if (!mpe)
1744  return;
1745 
1746  int trackID = mpe->m_trackID;
1747 
1748  if (m_currentPlaylist)
1749  {
1750  if (trackID == -1)
1751  {
1752  // more than one track has been added so easier to just reload the list
1753  updateUIPlaylist();
1754  }
1755  else
1756  {
1757  // just one track was added so just add that track to the end of the list
1758  MusicMetadata *mdata = gMusicData->m_all_music->getMetadata(trackID);
1759 
1760  if (mdata)
1761  {
1762  InfoMap metadataMap;
1763  mdata->toMap(metadataMap);
1764 
1765  auto *item = new MythUIButtonListItem(m_currentPlaylist, "",
1766  QVariant::fromValue(mdata));
1767 
1768  item->SetTextFromMap(metadataMap);
1769 
1771  mdata->ID() == gPlayer->getCurrentMetadata()->ID())
1772  {
1773  item->SetFontState("running");
1774  item->DisplayState("playing", "playstate");
1775  }
1776  else
1777  {
1778  item->SetFontState("normal");
1779  item->DisplayState("default", "playstate");
1780  }
1781 
1782  if (!gPlayer->getCurrentMetadata())
1784  }
1785 
1788  }
1789  }
1790 
1791  if (gPlayer->getCurrentPlaylist())
1794 
1795  updateUIPlaylist(); // else album art doesn't update
1798  }
1799  else if (event->type() == MusicPlayerEvent::kAllTracksRemovedEvent)
1800  {
1801  updateUIPlaylist();
1803  updateTrackInfo(nullptr);
1804  }
1805  else if (event->type() == MusicPlayerEvent::kMetadataChangedEvent ||
1807  {
1808  auto *mpe = dynamic_cast<MusicPlayerEvent *>(event);
1809 
1810  if (!mpe)
1811  return;
1812 
1813  uint trackID = mpe->m_trackID;
1814 
1815  if (m_currentPlaylist)
1816  {
1817  for (int x = 0; x < m_currentPlaylist->GetCount(); x++)
1818  {
1820  auto *mdata = item->GetData().value<MusicMetadata*>();
1821 
1822  if (mdata && mdata->ID() == trackID)
1823  {
1824  InfoMap metadataMap;
1825  mdata->toMap(metadataMap);
1826  item->SetTextFromMap(metadataMap);
1827 
1828  item->DisplayState(QString("%1").arg(mdata->Rating()), "ratingstate");
1829  }
1830  }
1831  }
1832 
1833  if (m_playedTracksList)
1834  {
1835  for (int x = 0; x < m_playedTracksList->GetCount(); x++)
1836  {
1838  auto *mdata = item->GetData().value<MusicMetadata*>();
1839 
1840  if (mdata && mdata->ID() == trackID)
1841  {
1842  InfoMap metadataMap;
1843  mdata->toMap(metadataMap);
1844  item->SetTextFromMap(metadataMap);
1845  }
1846  }
1847  }
1848 
1849  if (gPlayer->getCurrentMetadata() && trackID == gPlayer->getCurrentMetadata()->ID())
1851 
1852  // this will ensure the next track info gets updated
1853  if (gPlayer->getNextMetadata() && trackID == gPlayer->getNextMetadata()->ID())
1855  }
1856  else if (event->type() == MusicPlayerEvent::kAlbumArtChangedEvent)
1857  {
1858  auto *mpe = dynamic_cast<MusicPlayerEvent *>(event);
1859 
1860  if (!mpe)
1861  return;
1862 
1863  uint trackID = mpe->m_trackID;
1864 
1865  if (m_currentPlaylist)
1866  {
1867  for (int x = 0; x < m_currentPlaylist->GetCount(); x++)
1868  {
1870  auto *mdata = item->GetData().value<MusicMetadata*>();
1871  if (mdata && mdata->ID() == trackID)
1872  {
1873  // reload the albumart image if one has already been loaded for this track
1874  if (!item->GetImageFilename().isEmpty())
1875  {
1876  QString artFile = mdata->getAlbumArtFile();
1877  if (artFile.isEmpty())
1878  {
1879  item->SetImage("");
1880  item->SetImage("", "coverart");
1881  }
1882  else
1883  {
1884  item->SetImage(mdata->getAlbumArtFile());
1885  item->SetImage(mdata->getAlbumArtFile(), "coverart");
1886  }
1887  }
1888  }
1889  }
1890  }
1891 
1892  if (gPlayer->getCurrentMetadata() && trackID == gPlayer->getCurrentMetadata()->ID())
1894  }
1895  else if (event->type() == MusicPlayerEvent::kTrackUnavailableEvent)
1896  {
1897  auto *mpe = dynamic_cast<MusicPlayerEvent *>(event);
1898 
1899  if (!mpe)
1900  return;
1901 
1902  uint trackID = mpe->m_trackID;
1903 
1904  if (m_currentPlaylist)
1905  {
1906  for (int x = 0; x < m_currentPlaylist->GetCount(); x++)
1907  {
1909  auto *mdata = item->GetData().value<MusicMetadata*>();
1910  if (mdata && mdata->ID() == trackID)
1911  {
1912  item->SetFontState("disabled");
1913  item->DisplayState("unavailable", "playstate");
1914  }
1915  }
1916  }
1917  }
1918 }
1919 
1921 {
1922  if (!m_controlVolume)
1923  {
1924  if (m_volumeText)
1925  m_volumeText->Hide();
1926 
1927  if (m_muteState)
1928  m_muteState->Hide();
1929 
1930  return;
1931  }
1932 
1933  if (m_volumeText)
1934  {
1935  InfoMap map;
1936  gPlayer->toMap(map);
1938  }
1939 
1940  if (m_muteState)
1941  {
1942  bool muted = gPlayer->isMuted();
1943  m_muteState->DisplayState(muted ? "on" : "off");
1944  }
1945 }
1946 
1948 {
1949  if (!mdata)
1950  return;
1951 
1953 
1954  auto *editDialog = new EditMetadataDialog(mainStack, mdata);
1955 
1956  if (!editDialog->Create())
1957  {
1958  delete editDialog;
1959  return;
1960  }
1961 
1962  mainStack->AddScreen(editDialog);
1963 }
1964 
1966 {
1967  if (!mdata)
1968  {
1969  InfoMap metadataMap;
1970  MusicMetadata metadata;
1971  metadata.toMap(metadataMap);
1972  metadata.toMap(metadataMap, "next");
1973  ResetMap(metadataMap);
1974 
1975  if (m_coverartImage)
1977  if (m_ratingState)
1979  if (m_timeText)
1980  m_timeText->Reset();
1981  if (m_infoText)
1982  m_infoText->Reset();
1983  if (m_trackProgress)
1985 
1986  if (m_mainvisual)
1988 
1989  return;
1990  }
1991 
1993  m_maxTime = 0s;
1994  else
1995  m_maxTime = duration_cast<std::chrono::seconds>(mdata->Length());
1996 
1997  // get map for current track
1998  InfoMap metadataMap;
1999  mdata->toMap(metadataMap);
2000 
2001  // add the map from the next track
2002  MusicMetadata *nextMetadata = gPlayer->getNextMetadata();
2003  if (nextMetadata)
2004  nextMetadata->toMap(metadataMap, "next");
2005 
2006  // now set text using the map
2007  SetTextFromMap(metadataMap);
2008 
2009  if (m_coverartImage)
2010  {
2011  QString filename = mdata->getAlbumArtFile();
2012  if (!filename.isEmpty())
2013  {
2015  m_coverartImage->Load();
2016  }
2017  else
2018  {
2020  }
2021  }
2022 
2023  if (m_ratingState)
2024  m_ratingState->DisplayState(QString("%1").arg(mdata->Rating()));
2025 
2026  setTrackOnLCD(mdata);
2027 }
2028 
2030 {
2031  if (!mdata)
2032  return;
2033 
2034  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
2035 
2036  auto *dlg = new TrackInfoDialog(popupStack, mdata, "trackinfopopup");
2037 
2038  if (!dlg->Create())
2039  {
2040  delete dlg;
2041  return;
2042  }
2043 
2044  popupStack->AddScreen(dlg);
2045 }
2046 
2048 {
2049  if (!item)
2050  return;
2051 
2052  if (m_moveTrackMode)
2053  {
2055 
2056  if (m_movingTrack)
2057  item->DisplayState("on", "movestate");
2058  else
2059  item->DisplayState("off", "movestate");
2060  }
2061  else
2062  {
2064  }
2065 
2066  if (m_cycleVisualizer)
2067  cycleVisualizer();
2068 }
2069 
2071 {
2072  if (!item)
2073  return;
2074 
2075  auto *mdata = item->GetData().value<MusicMetadata*>();
2076  if (mdata && item->GetText() == " ")
2077  {
2078  if (item->GetImageFilename().isEmpty())
2079  {
2080  QString artFile = mdata->getAlbumArtFile();
2081  if (artFile.isEmpty())
2082  {
2083  item->SetImage("");
2084  item->SetImage("", "coverart");
2085  }
2086  else
2087  {
2088  item->SetImage(mdata->getAlbumArtFile());
2089  item->SetImage(mdata->getAlbumArtFile(), "coverart");
2090  }
2091  }
2092 
2093  InfoMap metadataMap;
2094  mdata->toMap(metadataMap);
2095  item->SetText("");
2096  item->SetTextFromMap(metadataMap);
2097  item->DisplayState(QString("%1").arg(mdata->Rating()), "ratingstate");
2098  }
2099 }
2100 
2102 {
2105 
2106  if (!m_currentPlaylist)
2107  return;
2108 
2110 
2111  m_currentTrack = -1;
2112 
2113  Playlist *playlist = gPlayer->getCurrentPlaylist();
2114 
2115  if (!playlist)
2116  return;
2117 
2118  for (int x = 0; x < playlist->getTrackCount(); x++)
2119  {
2120  MusicMetadata *mdata = playlist->getSongAt(x);
2121  if (mdata)
2122  {
2123  auto *item = new MythUIButtonListItem(m_currentPlaylist, " ",
2124  QVariant::fromValue(mdata));
2125 
2126  item->SetText(mdata->Artist() + mdata->Album() + mdata->Title(), "**search**");
2127  item->SetFontState("normal");
2128  item->DisplayState("default", "playstate");
2129 
2130  // if this is the current track update its play state to match the player
2131  if (gPlayer->getCurrentMetadata() && mdata->ID() == gPlayer->getCurrentMetadata()->ID())
2132  {
2133  if (gPlayer->isPlaying())
2134  {
2135  item->SetFontState("running");
2136  item->DisplayState("playing", "playstate");
2137  }
2138  else if (gPlayer->isPaused())
2139  {
2140  item->SetFontState("idle");
2141  item->DisplayState("paused", "playstate");
2142  }
2143  else
2144  {
2145  item->SetFontState("normal");
2146  item->DisplayState("stopped", "playstate");
2147  }
2148 
2151  }
2152  }
2153  }
2154 }
2155 
2157 {
2158  if (!m_playedTracksList)
2159  return;
2160 
2162 
2163  QList<MusicMetadata*> playedList = gPlayer->getPlayedTracksList();
2164 
2165  for (int x = playedList.count(); x > 0; x--)
2166  {
2167  MusicMetadata *mdata = playedList[x-1];
2168  auto *item = new MythUIButtonListItem(m_playedTracksList, "",
2169  QVariant::fromValue(mdata));
2170 
2171  InfoMap metadataMap;
2172  mdata->toMap(metadataMap);
2173  item->SetTextFromMap(metadataMap);
2174 
2175  item->SetFontState("normal");
2176  item->DisplayState("default", "playstate");
2177 
2178  item->SetImage(mdata->getAlbumArtFile());
2179  }
2180 }
2181 
2183 {
2184  int trackCount = 0;
2185 
2186  if (gPlayer->getCurrentPlaylist())
2187  trackCount = gPlayer->getCurrentPlaylist()->getTrackCount();
2188 
2189  InfoMap map;
2190  if (gPlayer->isPlaying() && trackCount > 0)
2191  {
2192  QString playlistcurrent = QLocale::system().toString(m_currentTrack + 1);
2193  QString playlisttotal = QLocale::system().toString(trackCount);
2194 
2195  map["playlistposition"] = tr("%1 of %2").arg(playlistcurrent, playlisttotal);
2196  map["playlistcurrent"] = playlistcurrent;
2197  map["playlistcount"] = playlisttotal;
2199  map["playlistplayedtime"] = getTimeString(m_playlistPlayedTime + m_currentTime, 0s);
2200  map["playlisttotaltime"] = getTimeString(m_playlistMaxTime, 0s);
2201  QString playlistName = gPlayer->getCurrentPlaylist() ? gPlayer->getCurrentPlaylist()->getName() : "";
2202  if (playlistName == "default_playlist_storage")
2203  playlistName = tr("Default Playlist");
2204  else if (playlistName == "stream_playlist")
2205  playlistName = tr("Stream Playlist");
2206  map["playlistname"] = playlistName;
2207  map["playedtime"] = getTimeString(m_currentTime, 0s); // v34 - parts
2208  map["totaltime"] = getTimeString(m_maxTime, 0s);
2209  map["trackspeed"] = getTimeString(-1s, 0s);
2210  }
2211  else
2212  {
2213  map["playlistposition"] = "";
2214  map["playlistcurrent"] = "";
2215  map["playlistcount"] = "";
2216  map["playlisttime"] = "";
2217  map["playlistplayedtime"] = "";
2218  map["playlisttotaltime"] = "";
2219  map["playlistname"] = "";
2220  map["playedtime"] = ""; // v34 - parts for track templates
2221  map["totaltime"] = "";
2222  map["trackspeed"] = "";
2223  }
2224 
2225  SetTextFromMap(map);
2226 
2227  if (m_playlistProgress)
2229 }
2230 
2231 QString MusicCommon::getTimeString(std::chrono::seconds exTime, std::chrono::seconds maxTime)
2232 {
2233  if (exTime > -1s && maxTime <= 0s)
2234  return MythDate::formatTime(exTime,
2235  (exTime >= 1h) ? "H:mm:ss" : "mm:ss");
2236 
2237  QString fmt = (maxTime >= 1h) ? "H:mm:ss" : "mm:ss";
2238  QString out = MythDate::formatTime(exTime, fmt)
2239  + " / " + MythDate::formatTime(maxTime, fmt);
2240  float speed = gPlayer->getSpeed(); // v34 - show altered speed
2241  QString speedstr = "";
2242  if (lroundf(speed * 100.0F) != 100.0F)
2243  {
2244  speedstr = QString("%1").arg(speed);
2245  out += ", " + speedstr + "X";
2246  }
2247  if (exTime <= -1s)
2248  return speedstr;
2249  return out;
2250 }
2251 
2253 {
2254  auto *buttonList = dynamic_cast<MythUIButtonList *>(GetFocusWidget());
2255  if (buttonList)
2256  buttonList->ShowSearchDialog();
2257 
2258  auto *buttonTree = dynamic_cast<MythUIButtonTree *>(GetFocusWidget());
2259  if (buttonTree)
2260  buttonTree->ShowSearchDialog();
2261 }
2262 
2264 {
2265  MythMenu *mainMenu = createMainMenu();
2266 
2267  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
2268 
2269  auto *menuPopup = new MythDialogBox(mainMenu, popupStack, "actionmenu");
2270 
2271  if (menuPopup->Create())
2272  popupStack->AddScreen(menuPopup);
2273  else
2274  delete mainMenu;
2275 }
2276 
2278 {
2279  QString label = tr("View Actions");
2280 
2281  auto *menu = new MythMenu(label, this, "mainmenu");
2282 
2284  {
2285  menu->AddItem(tr("Switch To Gallery View"));
2286  }
2288  {
2289  menu->AddItem(tr("Switch To Tree View"));
2290  }
2291 
2292  QStringList screenList;
2293  MythScreenType *screen = this;
2294  while (screen)
2295  {
2296  screenList.append(screen->objectName());
2297  screen = qobject_cast<MusicCommon*>(screen)->m_parentScreen;
2298  }
2299 
2300  if (!screenList.contains("visualizerview"))
2301  menu->AddItem(tr("Fullscreen Visualizer"));
2302 
2303  if (m_currentView == MV_PLAYLIST)
2304  menu->AddItem(tr("Browse Music Library")); // v33- was "Playlist Editor"
2305 
2306  if (m_currentView != MV_VISUALIZER) {
2307  if (!screenList.contains("searchview") && !screenList.contains("streamview"))
2308  menu->AddItem(tr("Search for Music"));
2309 
2310  if (!screenList.contains("lyricsview"))
2311  menu->AddItem(tr("Lyrics"));
2312  }
2313 
2314  menu->AddItem(tr("More Options"), nullptr, createSubMenu());
2315 
2316  return menu;
2317 }
2318 
2320 {
2321  QString label = tr("Actions");
2322 
2323  auto *menu = new MythMenu(label, this, "submenu");
2324 
2325  if (GetFocusWidget() && (GetFocusWidget()->inherits("MythUIButtonList") ||
2326  GetFocusWidget()->inherits("MythUIButtonTree")))
2327  menu->AddItem(tr("Search List..."));
2328 
2330  {
2331  menu->AddItem(tr("Playlist Options"), nullptr, createPlaylistMenu());
2332  menu->AddItem(tr("Set Shuffle Mode"), nullptr, createShuffleMenu());
2333  menu->AddItem(tr("Set Repeat Mode"), nullptr, createRepeatMenu());
2334  }
2335 
2336  menu->AddItem(tr("Player Options"), nullptr, createPlayerMenu());
2337 
2339  menu->AddItem(tr("Quick Playlists"), nullptr, createQuickPlaylistsMenu());
2340 
2341  if (m_visualizerVideo)
2342  menu->AddItem(tr("Change Visualizer"), nullptr, createVisualizerMenu());
2343 
2344  return menu;
2345 }
2346 
2348 {
2349  QString label = tr("Playlist Options");
2350 
2351  auto *menu = new MythMenu(label, this, "playlistmenu");
2352 
2353  if (m_currentPlaylist)
2354  {
2355  menu->AddItem(tr("Sync List With Current Track"));
2356  menu->AddItem(tr("Remove Selected Track"));
2357  }
2358 
2359  menu->AddItem(tr("Remove All Tracks"));
2360 
2361  if (m_currentPlaylist)
2362  {
2363  menu->AddItem(tr("Save To New Playlist"));
2364  menu->AddItem(tr("Save To Existing Playlist"));
2365 
2366  if (m_moveTrackMode)
2367  menu->AddItem(tr("Switch To Select Mode"));
2368  else
2369  menu->AddItem(tr("Switch To Move Mode"));
2370  }
2371 
2372  return menu;
2373 }
2374 
2376 {
2377  QString label = tr("Exiting Music Player.\n\n"
2378  "Do you want to continue playing in the background?");
2379 
2380  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
2381 
2382  auto *menu = new MythDialogBox(label, popupStack, "exitmenu");
2383 
2384  if (!menu->Create())
2385  {
2386  delete menu;
2387  return;
2388  }
2389 
2390  menu->SetReturnEvent(this, "exitmenu");
2391 
2392  menu->AddButton(tr("No - Exit, Stop Playing"));
2393  menu->AddButton(tr("Yes - Exit, Continue Playing"));
2394  menu->AddButton(tr("Cancel"));
2395 
2396  popupStack->AddScreen(menu);
2397 }
2398 
2400 {
2401  QString label = tr("Player Actions");
2402 
2403  auto *menu = new MythMenu(label, this, "playermenu");
2404 
2405  menu->AddItem(tr("Change Volume"));
2406  menu->AddItem(tr("Mute"));
2407  menu->AddItem(tr("Previous Track"));
2408  menu->AddItem(tr("Next Track"));
2409 
2411  {
2412  menu->AddItem(tr("Jump Back"));
2413  menu->AddItem(tr("Jump Forward"));
2414  }
2415 
2416  menu->AddItem(tr("Play"));
2417  menu->AddItem(tr("Stop"));
2418 
2420  menu->AddItem(tr("Pause"));
2421 
2422  return menu;
2423 }
2424 
2426 {
2427  QString label = tr("Set Repeat Mode");
2428 
2429  auto *menu = new MythMenu(label, this, "repeatmenu");
2430 
2431  menu->AddItemV(tr("None"), QVariant::fromValue((int)MusicPlayer::REPEAT_OFF));
2432  menu->AddItemV(tr("Track"), QVariant::fromValue((int)MusicPlayer::REPEAT_TRACK));
2433  menu->AddItemV(tr("All"), QVariant::fromValue((int)MusicPlayer::REPEAT_ALL));
2434 
2435  menu->SetSelectedByData(static_cast<int>(gPlayer->getRepeatMode()));
2436 
2437  return menu;
2438 }
2439 
2441 {
2442  QString label = tr("Set Shuffle Mode");
2443 
2444  auto *menu = new MythMenu(label, this, "shufflemenu");
2445 
2446  menu->AddItemV(tr("None"), QVariant::fromValue((int)MusicPlayer::SHUFFLE_OFF));
2447  menu->AddItemV(tr("Random"), QVariant::fromValue((int)MusicPlayer::SHUFFLE_RANDOM));
2448  menu->AddItemV(tr("Smart"), QVariant::fromValue((int)MusicPlayer::SHUFFLE_INTELLIGENT));
2449  menu->AddItemV(tr("Album"), QVariant::fromValue((int)MusicPlayer::SHUFFLE_ALBUM));
2450  menu->AddItemV(tr("Artist"), QVariant::fromValue((int)MusicPlayer::SHUFFLE_ARTIST));
2451 
2452  menu->SetSelectedByData(static_cast<int>(gPlayer->getShuffleMode()));
2453 
2454  return menu;
2455 }
2456 
2458 {
2459  QString label = tr("Quick Playlists");
2460 
2461  auto *menu = new MythMenu(label, this, "quickplaylistmenu");
2462 
2463  menu->AddItem(tr("All Tracks"));
2464 
2466  menu->AddItem(tr("From CD"));
2467 
2468  if (gPlayer->getCurrentMetadata())
2469  {
2470  menu->AddItem(tr("Tracks By Current Artist"));
2471  menu->AddItem(tr("Tracks From Current Album"));
2472  menu->AddItem(tr("Tracks From Current Genre"));
2473  menu->AddItem(tr("Tracks From Current Year"));
2474  menu->AddItem(tr("Tracks With Same Title"));
2475  }
2476 
2477  return menu;
2478 }
2479 
2481 {
2482  QString label = tr("Choose Visualizer");
2483 
2484  auto *menu = new MythMenu(label, this, "visualizermenu");
2485 
2486  for (uint x = 0; x < static_cast<uint>(m_visualModes.count()); x++)
2487  menu->AddItemV(m_visualModes.at(x), QVariant::fromValue(x));
2488 
2489  menu->SetSelectedByData(m_currentVisual);
2490 
2491  return menu;
2492 }
2493 
2495 {
2496  QString label = tr("Add to Playlist Options");
2497 
2498  auto *menu = new MythMenu(label, this, "playlistoptionsmenu");
2499 
2501  {
2502  menu->AddItem(tr("Play Now"));
2503  menu->AddItem(tr("Add Tracks"));
2504  menu->AddItem(tr("Replace Tracks"));
2505  menu->AddItem(tr("Prefer Add Tracks"));
2506  }
2507  else
2508  {
2509  menu->AddItem(tr("Add Tracks"));
2510  menu->AddItem(tr("Play Now"));
2511  menu->AddItem(tr("Replace Tracks"));
2512  menu->AddItem(tr("Prefer Play Now"));
2513  }
2514 
2515  return menu;
2516 }
2517 
2519 {
2520  m_whereClause = "ORDER BY music_artists.artist_name, album_name, disc_number, track";
2522 }
2523 
2525 {
2526  m_whereClause = "";
2527  m_songList.clear();
2528 
2529  // get the list of cd tracks
2530  for (int x = 1; x <= gMusicData->m_all_music->getCDTrackCount(); x++)
2531  {
2533  if (mdata)
2534  {
2535  m_songList.append((mdata)->ID());
2536  }
2537  }
2538 
2540 }
2541 
2543 {
2545  if (!mdata)
2546  return;
2547 
2548  QString value = formattedFieldValue(mdata->Artist().toUtf8().constData());
2549  m_whereClause = "WHERE music_artists.artist_name = " + value +
2550  " ORDER BY album_name, disc_number, track";
2551 
2553 }
2554 
2556 {
2558  if (!mdata)
2559  return;
2560 
2561  QString value = formattedFieldValue(mdata->Album().toUtf8().constData());
2562  m_whereClause = "WHERE album_name = " + value +
2563  " ORDER BY disc_number, track";
2564 
2566 }
2567 
2569 {
2571  if (!mdata)
2572  return;
2573 
2574  QString value = formattedFieldValue(mdata->Genre().toUtf8().constData());
2575  m_whereClause = "WHERE genre = " + value +
2576  " ORDER BY music_artists.artist_name, album_name, disc_number, track";
2577 
2579 }
2580 
2582 {
2584  if (!mdata)
2585  return;
2586 
2587  QString value = formattedFieldValue(mdata->Year());
2588  m_whereClause = "WHERE music_songs.year = " + value +
2589  " ORDER BY music_artists.artist_name, album_name, disc_number, track";
2590 
2592 }
2593 
2595 {
2597  if (!mdata)
2598  return;
2599 
2600  QString value = formattedFieldValue(mdata->Title().toUtf8().constData());
2601  m_whereClause = "WHERE music_songs.name = " + value +
2602  " ORDER BY music_artists.artist_name, album_name, disc_number, track";
2603 
2605 }
2606 
2608 {
2609  if (!gPlayer->getCurrentPlaylist())
2610  return;
2611 
2613 
2614  // Don't bother showing the dialog if the current playlist is empty
2615  if (gPlayer->getCurrentPlaylist()->getTrackCount() == 0)
2616  {
2618  doUpdatePlaylist();
2619  return;
2620  }
2621 
2623 
2624  if (addMainMenu)
2625  menu->AddItem(tr("More Options"), nullptr, createMainMenu());
2626 
2627  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
2628 
2629  auto *menuPopup = new MythDialogBox(menu, popupStack, "playlistoptionsmenu");
2630 
2631  if (menuPopup->Create())
2632  popupStack->AddScreen(menuPopup);
2633  else
2634  delete menu;
2635 }
2636 
2638 {
2639  int curTrackID = -1;
2640  int added = 0;
2641  int curPos = gPlayer->getCurrentTrackPos();
2642 
2643  // store id of current track
2644  if (gPlayer->getCurrentMetadata())
2645  curTrackID = gPlayer->getCurrentMetadata()->ID();
2646 
2647  if (!m_whereClause.isEmpty())
2648  {
2649  // update playlist from quick playlist
2651  m_whereClause, true,
2652  m_playlistOptions.insertPLOption, curTrackID);
2653  m_whereClause.clear();
2654  }
2655  else if (!m_songList.isEmpty())
2656  {
2657  // update playlist from song list (from the playlist editor)
2659  m_songList, true,
2660  m_playlistOptions.insertPLOption, curTrackID);
2661 
2662  m_songList.clear();
2663  }
2664 
2666 
2667  updateUIPlaylist();
2668  Playlist *playlist = gPlayer->getCurrentPlaylist();
2669  if (nullptr == playlist)
2670  return;
2671 
2672  // if (m_currentTrack == -1) // why? non-playing should also
2673  // playFirstTrack(); // start playing per options -twitham
2674  // else
2675  {
2677  {
2678  case PL_CURRENT:
2679  {
2680  if (!restorePosition(curTrackID))
2681  playFirstTrack();
2682 
2683  break;
2684  }
2685 
2686  case PL_FIRST:
2687  playFirstTrack();
2688  break;
2689 
2690  case PL_FIRSTNEW:
2691  {
2693  {
2694  case PL_REPLACE:
2695  playFirstTrack();
2696  break;
2697 
2698  case PL_INSERTATEND:
2699  {
2700  pause();
2701  if (!gPlayer->setCurrentTrackPos(playlist->getTrackCount() - added))
2702  playFirstTrack();
2703  break;
2704  }
2705 
2706  case PL_INSERTAFTERCURRENT:
2707  if (!gPlayer->setCurrentTrackPos(curPos + 1))
2708  playFirstTrack();
2709  break;
2710 
2711  default:
2712  playFirstTrack();
2713  }
2714 
2715  break;
2716  }
2717  }
2718  }
2719 
2724 }
2725 
2727 {
2728  // try to move to the current track
2729  bool foundTrack = false;
2730 
2731  Playlist *playlist = gPlayer->getCurrentPlaylist();
2732  if (nullptr == playlist)
2733  return false;
2734 
2735  if (trackID != -1)
2736  {
2737  for (int x = 0; x < playlist->getTrackCount(); x++)
2738  {
2739  MusicMetadata *mdata = playlist->getSongAt(x);
2740  if (mdata && mdata->ID() == (MusicMetadata::IdType) trackID)
2741  {
2742  m_currentTrack = x;
2743  if (m_currentPlaylist)
2744  {
2747  if (item)
2748  {
2749  item->SetFontState("running");
2750  item->DisplayState("playing", "playstate");
2751  }
2752  }
2753 
2754  foundTrack = true;
2755 
2756  break;
2757  }
2758  }
2759  }
2760 
2761  return foundTrack;
2762 }
2763 
2765 {
2767 }
2768 
2769 //---------------------------------------------------------
2770 // MythMusicVolumeDialog
2771 //---------------------------------------------------------
2772 static constexpr std::chrono::milliseconds MUSICVOLUMEPOPUPTIME { 4s };
2773 
2775 {
2776  if (m_displayTimer)
2777  {
2778  m_displayTimer->stop();
2779  delete m_displayTimer;
2780  m_displayTimer = nullptr;
2781  }
2782 }
2783 
2785 {
2786  if (!LoadWindowFromXML("music-ui.xml", "volume_popup", this))
2787  return false;
2788 
2789  UIUtilW::Assign(this, m_volText, "volume");
2790  UIUtilW::Assign(this, m_volProgress, "volumeprogress");
2791  UIUtilW::Assign(this, m_muteState, "mutestate");
2792 
2793  if (m_volProgress)
2794  m_volProgress->SetTotal(100);
2795 
2796  updateDisplay();
2797 
2798  m_displayTimer = new QTimer(this);
2800  m_displayTimer->setSingleShot(true);
2802 
2803  return true;
2804 }
2805 
2807 {
2808  QStringList actions;
2809  bool handled = GetMythMainWindow()->TranslateKeyPress("Music", event, actions, false);
2810 
2811  for (int i = 0; i < actions.size() && !handled; i++)
2812  {
2813  const QString& action = actions[i];
2814  handled = true;
2815 
2816  if (action == "UP" || action == "VOLUMEUP")
2817  increaseVolume();
2818  else if (action == "DOWN" || action == "VOLUMEDOWN")
2819  decreaseVolume();
2820  else if (action == "MUTE" || action == "SELECT")
2821  toggleMute();
2822  else
2823  handled = false;
2824  }
2825 
2826  if (!handled && MythScreenType::keyPressEvent(event))
2827  handled = true;
2828 
2829  // Restart the display timer only if we handled this keypress, if nothing
2830  // has changed there's no need to keep the volume on-screen
2831  if (handled)
2833 
2834  return handled;
2835 }
2836 
2838 {
2839  gPlayer->incVolume();
2840  updateDisplay();
2841 }
2842 
2844 {
2845  gPlayer->decVolume();
2846  updateDisplay();
2847 }
2848 
2850 {
2851  gPlayer->toggleMute();
2852  updateDisplay();
2853 }
2854 
2856 {
2857  if (m_muteState)
2858  m_muteState->DisplayState(gPlayer->isMuted() ? "on" : "off");
2859 
2860  if (m_volProgress)
2862 
2863  if (m_volText)
2864  {
2865  InfoMap map;
2866  gPlayer->toMap(map);
2867  m_volText->SetTextFromMap(map);
2868  }
2869 }
2870 
2871 //---------------------------------------------------------
2872 // TrackInfoDialog
2873 //---------------------------------------------------------
2875 {
2876  if (!LoadWindowFromXML("music-ui.xml", "trackdetail_popup", this))
2877  return false;
2878 
2879  InfoMap metadataMap;
2880  m_metadata->toMap(metadataMap);
2881  SetTextFromMap(metadataMap);
2882 
2883  MythUIStateType *ratingState = dynamic_cast<MythUIStateType *>(GetChild("rating_state"));
2884  if (ratingState)
2885  ratingState->DisplayState(QString("%1").arg(m_metadata->Rating()));
2886 
2887  MythUIImage *albumImage = dynamic_cast<MythUIImage *>(GetChild("coverart"));
2888  if (albumImage)
2889  {
2890  if (!m_metadata->getAlbumArtFile().isEmpty())
2891  {
2892  albumImage->SetFilename(m_metadata->getAlbumArtFile());
2893  albumImage->Load();
2894  }
2895  }
2896 
2897  // hide the song ID by default
2898  MythUIText *songID = dynamic_cast<MythUIText *>(GetChild("songid"));
2899  if (songID)
2900  songID->Hide();
2901 
2902  return true;
2903 }
2904 
2905 bool TrackInfoDialog::keyPressEvent(QKeyEvent *event)
2906 {
2907  QStringList actions;
2908  bool handled = GetMythMainWindow()->TranslateKeyPress("Music", event, actions, false);
2909 
2910  for (int i = 0; i < actions.size() && !handled; i++)
2911  {
2912  const QString& action = actions[i];
2913  handled = true;
2914 
2915  if (action == "INFO")
2916  Close();
2917  if (action == "0")
2918  {
2919  // if it's available show the song ID
2920  MythUIText *songID = dynamic_cast<MythUIText *>(GetChild("songid"));
2921  if (songID)
2922  songID->Show();
2923  }
2924  else
2925  {
2926  handled = false;
2927  }
2928  }
2929 
2930  if (!handled && MythScreenType::keyPressEvent(event))
2931  handled = true;
2932 
2933  return handled;
2934 }
LCD::MUSIC_SHUFFLE_ALBUM
@ MUSIC_SHUFFLE_ALBUM
Definition: lcddevice.h:194
MusicPlayer::addVisual
void addVisual(MainVisual *visual)
Definition: musicplayer.cpp:178
MythMusicVolumeDialog::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: musiccommon.cpp:2806
MythUIButton::Clicked
void Clicked()
MusicCommon::m_currentView
MusicView m_currentView
Definition: musiccommon.h:141
MusicCommon::stopAll
void stopAll(void)
Definition: musiccommon.cpp:1093
MythUIButtonList::GetItemAt
MythUIButtonListItem * GetItemAt(int pos) const
Definition: mythuibuttonlist.cpp:1700
MusicPlayer::REPEAT_TRACK
@ REPEAT_TRACK
Definition: musicplayer.h:170
MusicPlayer::toggleMute
void toggleMute(void)
Definition: musicplayer.cpp:1433
MusicCommon::m_movingTracksState
MythUIStateType * m_movingTracksState
Definition: musiccommon.h:181
mythuibuttontree.h
MusicPlayer::getDecoder
Decoder * getDecoder(void)
Definition: musicplayer.h:126
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:317
MusicCommon::init
void init(bool startPlayback=true)
Definition: musiccommon.cpp:162
MusicCommon::editTrackInfo
static void editTrackInfo(MusicMetadata *mdata)
Definition: musiccommon.cpp:1947
playlistcontainer.h
MusicCommon::m_trackProgressText
MythUIText * m_trackProgressText
Definition: musiccommon.h:186
MusicPlayer::getOutput
AudioOutput * getOutput(void)
Definition: musicplayer.h:128
MythUISearchDialog
Provide a dialog to quickly find an entry in a list.
Definition: mythdialogbox.h:398
MusicMetadata::Title
QString Title() const
Definition: musicmetadata.h:161
MythUIButton::SetLocked
void SetLocked(bool locked)
Definition: mythuibutton.cpp:206
gPlayer
MusicPlayer * gPlayer
Definition: musicplayer.cpp:38
MusicCommon::m_currentTrack
int m_currentTrack
Definition: musiccommon.h:157
Playlist::getSongAt
MusicMetadata * getSongAt(int pos) const
Definition: playlist.cpp:1096
LCD::MUSIC_SHUFFLE_ARTIST
@ MUSIC_SHUFFLE_ARTIST
Definition: lcddevice.h:195
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1614
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:101
formattedFieldValue
QString formattedFieldValue(const QVariant &value)
Definition: smartplaylist.cpp:104
MusicPlayer::SHUFFLE_ARTIST
@ SHUFFLE_ARTIST
Definition: musicplayer.h:179
MusicPlayer::setCurrentTrackPos
bool setCurrentTrackPos(int pos)
Definition: musicplayer.cpp:1064
mythuitext.h
MusicPlayer::getRepeatMode
RepeatMode getRepeatMode(void)
Definition: musicplayer.h:191
mythuiprogressbar.h
MythMusicVolumeDialog
Definition: musiccommon.h:211
MythUIImage
Image widget, displays a single image or multiple images in sequence.
Definition: mythuiimage.h:97
MV_PLAYLIST
@ MV_PLAYLIST
Definition: musiccommon.h:33
MythMusicVolumeDialog::m_volText
MythUIText * m_volText
Definition: musiccommon.h:231
MusicCommon::m_repeatState
MythUIStateType * m_repeatState
Definition: musiccommon.h:179
DialogCompletionEvent::GetId
QString GetId()
Definition: mythdialogbox.h:51
MusicMetadata::Genre
QString Genre() const
Definition: musicmetadata.h:174
MythUIText::Reset
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuitext.cpp:65
editmetadata.h
MusicCommon::setTrackOnLCD
static void setTrackOnLCD(MusicMetadata *mdata)
Definition: musiccommon.cpp:1081
MusicCommon::m_playButton
MythUIButton * m_playButton
Definition: musiccommon.h:198
MusicPlayer::toMap
void toMap(InfoMap &infoMap) const
Definition: musicplayer.cpp:1449
MusicCommon::m_whereClause
QString m_whereClause
Definition: musiccommon.h:167
mythuivideo.h
MusicCommon::m_trackSpeedText
MythUIText * m_trackSpeedText
Definition: musiccommon.h:187
MusicCommon::seekforward
void seekforward(void)
Definition: musiccommon.cpp:1142
MusicCommon::m_ffButton
MythUIButton * m_ffButton
Definition: musiccommon.h:200
MythMusicVolumeDialog::increaseVolume
void increaseVolume(void)
Definition: musiccommon.cpp:2837
mythrandom.h
MythUIButtonListItem::DisplayState
void DisplayState(const QString &state, const QString &name)
Definition: mythuibuttonlist.cpp:3613
MusicCommon::switchView
void switchView(MusicView view)
Definition: musiccommon.cpp:377
MythUIComposite::ResetMap
virtual void ResetMap(const InfoMap &infoMap)
Definition: mythuicomposite.cpp:28
MusicPlayer::SHUFFLE_OFF
@ SHUFFLE_OFF
Definition: musicplayer.h:175
MusicPlayer::REPEAT_ALL
@ REPEAT_ALL
Definition: musicplayer.h:171
OutputEvent
Definition: output.h:31
MusicCommon::CreateCommon
bool CreateCommon(void)
Definition: musiccommon.cpp:78
MusicPlayerEvent
Definition: musicplayer.h:20
MusicCommon::createPlaylistOptionsMenu
MythMenu * createPlaylistOptionsMenu(void)
Definition: musiccommon.cpp:2494
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:384
PlaylistEditorView
Definition: playlisteditorview.h:65
PL_FIRSTNEW
@ PL_FIRSTNEW
Definition: playlist.h:33
MusicCommon::keyPressEvent
bool keyPressEvent(QKeyEvent *e) override
Key event handler.
Definition: musiccommon.cpp:587
MV_PLAYLISTEDITORTREE
@ MV_PLAYLISTEDITORTREE
Definition: musiccommon.h:35
TrackInfoDialog::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: musiccommon.cpp:2905
MusicPlayer::PLAYMODE_TRACKSPLAYLIST
@ PLAYMODE_TRACKSPLAYLIST
Definition: musicplayer.h:71
MythUIType::GetChild
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
Definition: mythuitype.cpp:138
MusicCommon::showPlaylistOptionsMenu
void showPlaylistOptionsMenu(bool addMainMenu=false)
Definition: musiccommon.cpp:2607
MusicCommon::playlistItemClicked
void playlistItemClicked(MythUIButtonListItem *item)
Definition: musiccommon.cpp:2047
MythUIButtonList::RemoveItem
void RemoveItem(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1512
MusicCommon::createVisualizerMenu
MythMenu * createVisualizerMenu(void)
Definition: musiccommon.cpp:2480
MusicCommon::m_songList
QList< int > m_songList
Definition: musiccommon.h:170
MusicCommon::m_fullscreenBlank
bool m_fullscreenBlank
Definition: musiccommon.h:145
MusicCommon::m_muteState
MythUIStateType * m_muteState
Definition: musiccommon.h:190
MythUIImage::Load
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Definition: mythuiimage.cpp:971
MusicPlayer::decVolume
void decVolume(void)
Definition: musicplayer.cpp:1408
MusicPlayer::PLAYMODE_TRACKSEDITOR
@ PLAYMODE_TRACKSEDITOR
Definition: musicplayer.h:72
MusicCommon::previous
void previous(void)
Definition: musiccommon.cpp:1134
MusicCommon::createSubMenu
MythMenu * createSubMenu(void)
Definition: musiccommon.cpp:2319
PL_INSERTAFTERCURRENT
@ PL_INSERTAFTERCURRENT
Definition: playlist.h:27
PlaylistOptions::insertPLOption
InsertPLOption insertPLOption
Definition: playlist.h:39
Playlist
Definition: playlist.h:45
Playlist::getName
QString getName(void)
Definition: playlist.h:106
MusicCommon::toggleMute
void toggleMute(void) const
Definition: musiccommon.cpp:945
MusicPlayer::getPlayNow
static bool getPlayNow(void)
Definition: musicplayer.cpp:230
TrackInfoDialog
Definition: musiccommon.h:236
MusicCommon::updatePlaylistStats
void updatePlaylistStats(void)
Definition: musiccommon.cpp:2182
MusicCommon::seekback
void seekback(void)
Definition: musiccommon.cpp:1149
MusicPlayer::PLAYMODE_RADIO
@ PLAYMODE_RADIO
Definition: musicplayer.h:73
MythUIProgressBar::SetUsed
void SetUsed(int value)
Definition: mythuiprogressbar.cpp:72
MUSICVOLUMEPOPUPTIME
static constexpr std::chrono::milliseconds MUSICVOLUMEPOPUPTIME
Definition: musiccommon.cpp:2772
mythdialogbox.h
MythScreenStack
Definition: mythscreenstack.h:16
MusicCommon::byTitle
void byTitle(void)
Definition: musiccommon.cpp:2594
MythDate::formatTime
QString formatTime(std::chrono::milliseconds msecs, QString fmt)
Format a milliseconds time value.
Definition: mythdate.cpp:242
MusicPlayer::setShuffleMode
void setShuffleMode(ShuffleMode mode)
Definition: musicplayer.cpp:1274
MusicMetadata::ID
IdType ID() const
Definition: musicmetadata.h:217
MusicCommon::next
void next(void)
Definition: musiccommon.cpp:1125
MusicCommon::doUpdatePlaylist
void doUpdatePlaylist(void)
Definition: musiccommon.cpp:2637
MusicCommon::~MusicCommon
~MusicCommon(void) override
Definition: musiccommon.cpp:60
MusicCommon::playFirstTrack
static void playFirstTrack()
Definition: musiccommon.cpp:2764
MusicPlayer::getCurrentTrackPos
int getCurrentTrackPos(void) const
Definition: musicplayer.h:143
MusicPlayer::isPlaying
bool isPlaying(void) const
Definition: musicplayer.h:109
MusicCommon::m_ratingState
MythUIStateType * m_ratingState
Definition: musiccommon.h:183
MusicCommon::m_rewButton
MythUIButton * m_rewButton
Definition: musiccommon.h:196
PlaylistContainer::copyNewPlaylist
void copyNewPlaylist(const QString &name)
Definition: playlistcontainer.cpp:193
MusicCommon::showTrackInfo
static void showTrackInfo(MusicMetadata *mdata)
Definition: musiccommon.cpp:2029
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MusicCommon::m_pauseButton
MythUIButton * m_pauseButton
Definition: musiccommon.h:197
MythUIButton::SetLockable
void SetLockable(bool lockable)
Definition: mythuibutton.h:39
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
mythuistatetype.h
show
static void show(uint8_t *buf, int length)
Definition: ringbuffer.cpp:341
MusicCommon::fromCD
void fromCD(void)
Definition: musiccommon.cpp:2524
playlisteditorview.h
MusicMetadata
Definition: musicmetadata.h:80
MusicCommon::createPlaylistMenu
MythMenu * createPlaylistMenu(void)
Definition: musiccommon.cpp:2347
MusicPlayerEvent::kMetadataChangedEvent
static const Type kMetadataChangedEvent
Definition: musicplayer.h:45
MusicCommon::switchVisualizer
void switchVisualizer(const QString &visual)
Definition: musiccommon.cpp:1014
PlaylistContainer::getPlaylistNames
QStringList getPlaylistNames(void)
Definition: playlistcontainer.cpp:286
MusicMetadata::Length
std::chrono::milliseconds Length() const
Definition: musicmetadata.h:204
MusicPlayer::getCurrentPlaylist
Playlist * getCurrentPlaylist(void)
Definition: musicplayer.cpp:1637
MythUIButtonList::SetSearchFields
void SetSearchFields(const QString &fields)
Definition: mythuibuttonlist.h:256
playlistview.h
MythUIImage::Reset
void Reset(void) override
Reset the image back to the default defined in the theme.
Definition: mythuiimage.cpp:644
MusicPlayer::removeListener
void removeListener(QObject *listener)
Definition: musicplayer.cpp:162
MV_PLAYLISTEDITORGALLERY
@ MV_PLAYLISTEDITORGALLERY
Definition: musiccommon.h:36
PL_CURRENT
@ PL_CURRENT
Definition: playlist.h:34
startPlayback
static void startPlayback(void)
Definition: mythfrontend.cpp:595
MusicMetadata::Artist
QString Artist() const
Definition: musicmetadata.h:125
MainVisual::prepare
void prepare(void) override
Definition: mainvisual.cpp:138
MusicPlayer::setPlayMode
void setPlayMode(PlayMode mode)
Definition: musicplayer.cpp:972
MusicPlayer::pause
void pause(void)
Definition: musicplayer.cpp:299
mythuibuttonlist.h
PlaylistView
Definition: playlistview.h:17
LCD::Get
static LCD * Get(void)
Definition: lcddevice.cpp:69
MusicPlayer::getPlayMode
PlayMode getPlayMode(void)
Definition: musicplayer.h:77
mythuiimage.h
MythUIButtonList::GetCount
int GetCount() const
Definition: mythuibuttonlist.cpp:1679
Playlist::toRawSonglist
QString toRawSonglist(bool shuffled=false, bool tracksOnly=false)
Definition: playlist.cpp:855
MythMusicVolumeDialog::Create
bool Create(void) override
Definition: musiccommon.cpp:2784
MusicPlayer::isStopped
bool isStopped(void)
Definition: musicplayer.h:111
MusicCommon::play
static void play(void)
Definition: musiccommon.cpp:1105
MusicCommon::changeSpeed
void changeSpeed(bool up)
Definition: musiccommon.cpp:932
MusicPlayerEvent::kAllTracksRemovedEvent
static const Type kAllTracksRemovedEvent
Definition: musicplayer.h:44
MythMusicVolumeDialog::m_displayTimer
QTimer * m_displayTimer
Definition: musiccommon.h:229
VisualizerView
Definition: visualizerview.h:17
MusicPlayer::changeCurrentTrack
void changeCurrentTrack(int trackNo)
change the current track to the given track
Definition: musicplayer.cpp:1166
AllMusic::getCDMetadata
MusicMetadata * getCDMetadata(int m_the_track)
Definition: musicmetadata.cpp:1721
MusicCommon::byArtist
void byArtist(void)
Definition: musiccommon.cpp:2542
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:111
Playlist::fillSonglistFromQuery
int fillSonglistFromQuery(const QString &whereClause, bool removeDuplicates=false, InsertPLOption insertOption=PL_REPLACE, int currentTrackID=0)
Definition: playlist.cpp:686
MainVisual::setVisual
void setVisual(const QString &name)
Definition: mainvisual.cpp:80
PlaylistContainer::getActive
Playlist * getActive(void)
Definition: playlistcontainer.h:47
MusicCommon::m_visualModes
QStringList m_visualModes
Definition: musiccommon.h:149
MusicCommon::m_playlistOptions
PlaylistOptions m_playlistOptions
Definition: musiccommon.h:166
InfoMap
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
MythUIButtonListItem::SetText
void SetText(const QString &text, const QString &name="", const QString &state="")
Definition: mythuibuttonlist.cpp:3319
LCD::MUSIC_SHUFFLE_SMART
@ MUSIC_SHUFFLE_SMART
Definition: lcddevice.h:193
MusicPlayer::sendTrackStatsChangedEvent
void sendTrackStatsChangedEvent(int trackID)
Definition: musicplayer.cpp:1375
MusicPlayer::getCurrentMetadata
MusicMetadata * getCurrentMetadata(void)
get the metadata for the current track in the playlist
Definition: musicplayer.cpp:1189
MusicCommon::showVolume
static void showVolume(void)
Definition: musiccommon.cpp:995
MusicCommon::m_currentTime
std::chrono::seconds m_currentTime
Definition: musiccommon.h:158
MythUIButtonListItem
Definition: mythuibuttonlist.h:41
LCD::MUSIC_SHUFFLE_NONE
@ MUSIC_SHUFFLE_NONE
Definition: lcddevice.h:191
MusicCommon::m_moveTrackMode
bool m_moveTrackMode
Definition: musiccommon.h:152
mythdate.h
OutputEvent::kStopped
static const Type kStopped
Definition: output.h:67
MusicCommon::getTimeString
static QString getTimeString(std::chrono::seconds exTime, std::chrono::seconds maxTime)
Definition: musiccommon.cpp:2231
MusicPlayer::toggleRepeatMode
RepeatMode toggleRepeatMode(void)
Definition: musicplayer.cpp:1228
Decoder
Definition: decoder.h:70
MusicCommon::m_currentVisual
unsigned int m_currentVisual
Definition: musiccommon.h:150
MythUIProgressBar::SetTotal
void SetTotal(int value)
Definition: mythuiprogressbar.cpp:78
MusicPlayer::removeVisual
void removeVisual(MainVisual *visual)
Definition: musicplayer.cpp:192
MusicCommon::m_maxTime
std::chrono::seconds m_maxTime
Definition: musiccommon.h:159
MythUIType::Show
void Show(void)
Definition: mythuitype.cpp:1144
mythlogging.h
MV_RADIO
@ MV_RADIO
Definition: musiccommon.h:42
MusicPlayer::incVolume
void incVolume(void)
Definition: musicplayer.cpp:1399
MusicCommon::byYear
void byYear(void)
Definition: musiccommon.cpp:2581
MusicCommon::m_cycleVisualizer
bool m_cycleVisualizer
Definition: musiccommon.h:146
Decoder::unlock
virtual void unlock(void)
Definition: decoder.h:86
MythUIButtonList::itemClicked
void itemClicked(MythUIButtonListItem *item)
MythMainWindow::TranslateKeyPress
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
Definition: mythmainwindow.cpp:1111
Playlist::changed
void changed(void)
Definition: playlist.cpp:990
MythUIButtonList::GetCurrentPos
int GetCurrentPos() const
Definition: mythuibuttonlist.h:240
MusicCommon::m_playlistTrackCount
uint m_playlistTrackCount
Definition: musiccommon.h:161
MusicMetadata::toMap
void toMap(InfoMap &metadataMap, const QString &prefix="")
Definition: musicmetadata.cpp:1103
MusicPlayer::toggleShuffleMode
ShuffleMode toggleShuffleMode(void)
Definition: musicplayer.cpp:1247
MusicPlayerEvent::kTrackChangeEvent
static const Type kTrackChangeEvent
Definition: musicplayer.h:39
MusicCommon::m_playlistProgress
MythUIProgressBar * m_playlistProgress
Definition: musiccommon.h:193
MusicCommon::playlistItemVisible
static void playlistItemVisible(MythUIButtonListItem *item)
Definition: musiccommon.cpp:2070
MythDialogBox
Basic menu dialog, message and a list of options.
Definition: mythdialogbox.h:165
menu
static MythThemedMenu * menu
Definition: mythtv-setup.cpp:58
MusicMetadata::getAlbumArtFile
QString getAlbumArtFile(void)
Definition: musicmetadata.cpp:1277
OutputEvent::kInfo
static const Type kInfo
Definition: output.h:65
MusicCommon::byGenre
void byGenre(void)
Definition: musiccommon.cpp:2568
MythTV::Visual::mutex
QMutex * mutex()
Definition: visual.h:26
searchview.h
MusicCommon::m_prevButton
MythUIButton * m_prevButton
Definition: musiccommon.h:195
MusicCommon::createQuickPlaylistsMenu
MythMenu * createQuickPlaylistsMenu(void)
Definition: musiccommon.cpp:2457
MusicPlayer::ShuffleMode
ShuffleMode
Definition: musicplayer.h:174
LCD::MUSIC_REPEAT_NONE
@ MUSIC_REPEAT_NONE
Definition: lcddevice.h:185
MusicCommon::m_playlistMaxTime
std::chrono::seconds m_playlistMaxTime
Definition: musiccommon.h:163
Playlist::getTrackCount
int getTrackCount(void)
Definition: playlist.h:82
MusicPlayerEvent::kTrackStatsChangedEvent
static const Type kTrackStatsChangedEvent
Definition: musicplayer.h:46
EditMetadataDialog
Definition: editvideometadata.h:19
MythUIComposite::SetTextFromMap
virtual void SetTextFromMap(const InfoMap &infoMap)
Definition: mythuicomposite.cpp:9
PlaylistContainer::getPlaylist
Playlist * getPlaylist(int id)
Definition: playlistcontainer.cpp:134
MythUIButton::Push
void Push(bool lock=false)
Definition: mythuibutton.cpp:175
MusicCommon::m_currentPlaylist
MythUIButtonList * m_currentPlaylist
Definition: musiccommon.h:205
MusicPlayer::incSpeed
void incSpeed()
Definition: musicplayer.cpp:1351
MythUIButtonTree
A tree widget for displaying and navigating a MythGenericTree()
Definition: mythuibuttontree.h:16
MusicCommon::updateProgressBar
void updateProgressBar(void)
Definition: musiccommon.cpp:960
MusicPlayer::RepeatMode
RepeatMode
Definition: musicplayer.h:168
MusicCommon::stopVisualizer
void stopVisualizer(void)
Definition: musiccommon.cpp:1073
AllMusic::getCDTrackCount
int getCDTrackCount(void) const
Definition: musicmetadata.h:441
MusicCommon::m_mainvisual
MainVisual * m_mainvisual
Definition: musiccommon.h:144
MythMusicVolumeDialog::m_muteState
MythUIStateType * m_muteState
Definition: musiccommon.h:232
MusicCommon::createRepeatMenu
MythMenu * createRepeatMenu(void)
Definition: musiccommon.cpp:2425
MusicPlayer::getShuffleMode
ShuffleMode getShuffleMode(void)
Definition: musicplayer.h:195
MusicPlayerEvent::m_trackID
int m_trackID
Definition: musicplayer.h:33
MusicPlayer::savePosition
void savePosition(void)
Definition: musicplayer.cpp:1079
MusicCommon::viewExited
void viewExited(void)
Definition: musiccommon.cpp:582
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3715
MusicPlayer::playlistChanged
void playlistChanged(int playlistID)
Definition: musicplayer.cpp:1522
AllMusic::getMetadata
MusicMetadata * getMetadata(int an_id)
Definition: musicmetadata.cpp:1651
MusicPlayer::removeTrack
void removeTrack(int trackID)
Definition: musicplayer.cpp:1616
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
clamp
static eu8 clamp(eu8 value, eu8 low, eu8 high)
Definition: pxsup2dast.c:204
MusicData::m_all_playlists
PlaylistContainer * m_all_playlists
Definition: musicdata.h:51
MusicPlayer::next
void next(void)
Definition: musicplayer.cpp:431
MusicPlayer::isPaused
bool isPaused(void)
Definition: musicplayer.h:110
MusicCommon::updateUIPlayedList
void updateUIPlayedList(void)
Definition: musiccommon.cpp:2156
smartplaylist.h
MusicCommon::updateRepeatMode
void updateRepeatMode(void)
Definition: musiccommon.cpp:287
MusicCommon::m_trackState
MythUIStateType * m_trackState
Definition: musiccommon.h:188
MusicCommon::createShuffleMenu
MythMenu * createShuffleMenu(void)
Definition: musiccommon.cpp:2440
PL_FIRST
@ PL_FIRST
Definition: playlist.h:32
MusicCommon::m_coverartImage
MythUIImage * m_coverartImage
Definition: musiccommon.h:203
LyricsView
Definition: lyricsview.h:17
MythUIButtonList::itemVisible
void itemVisible(MythUIButtonListItem *item)
MV_LYRICS
@ MV_LYRICS
Definition: musiccommon.h:34
MusicCommon::m_infoText
MythUIText * m_infoText
Definition: musiccommon.h:174
musicdata.h
UIUtilDisp::Assign
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
TrackInfoDialog::m_metadata
MusicMetadata * m_metadata
Definition: musiccommon.h:249
LCD::MUSIC_REPEAT_ALL
@ MUSIC_REPEAT_ALL
Definition: lcddevice.h:187
MythUIType::Hide
void Hide(void)
Definition: mythuitype.cpp:1139
MythMusicVolumeDialog::toggleMute
void toggleMute(void)
Definition: musiccommon.cpp:2849
MythUIButtonListItem::SetTextFromMap
void SetTextFromMap(const InfoMap &infoMap, const QString &state="")
Definition: mythuibuttonlist.cpp:3338
OutputEvent::kPlaying
static const Type kPlaying
Definition: output.h:63
musiccommon.h
MusicCommon::m_visualizerVideo
MythUIVideo * m_visualizerVideo
Definition: musiccommon.h:208
MusicMetadata::Album
QString Album() const
Definition: musicmetadata.h:149
MusicCommon::createPlayerMenu
MythMenu * createPlayerMenu(void)
Definition: musiccommon.cpp:2399
gMusicData
MusicData * gMusicData
Definition: musicdata.cpp:23
streamview.h
MusicView
MusicView
Definition: musiccommon.h:31
PL_INSERTATEND
@ PL_INSERTATEND
Definition: playlist.h:26
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:912
MusicCommon::changeRating
static void changeRating(bool increase)
Definition: musiccommon.cpp:1208
MusicPlayerEvent::kTrackUnavailableEvent
static const Type kTrackUnavailableEvent
Definition: musicplayer.h:43
MythUIButtonListItem::GetText
QString GetText(const QString &name="") const
Definition: mythuibuttonlist.cpp:3368
MusicCommon::m_stopButton
MythUIButton * m_stopButton
Definition: musiccommon.h:199
MusicMetadata::IdType
uint32_t IdType
Definition: musicmetadata.h:86
MusicPlayer::getNextMetadata
MusicMetadata * getNextMetadata(void)
get the metadata for the next track in the playlist
Definition: musicplayer.cpp:1202
MusicCommon::m_timeText
MythUIText * m_timeText
Definition: musiccommon.h:173
MainVisual::getVisualizations
QStringList getVisualizations(void)
Definition: mainvisual.h:58
MainVisual::getCurrentVisual
int getCurrentVisual(void) const
Definition: mainvisual.h:60
MusicCommon::updateVolume
void updateVolume(void)
Definition: musiccommon.cpp:1920
MusicCommon::updateTrackInfo
void updateTrackInfo(MusicMetadata *mdata)
Definition: musiccommon.cpp:1965
MainVisual
Definition: mainvisual.h:34
MusicPlayer::getPlayedTracksList
QList< MusicMetadata * > & getPlayedTracksList(void)
Definition: musicplayer.h:141
MusicCommon::m_trackProgress
MythUIProgressBar * m_trackProgress
Definition: musiccommon.h:185
MusicCommon::createMainMenu
MythMenu * createMainMenu(void)
Definition: musiccommon.cpp:2277
MythUIButtonListItem::SetFontState
void SetFontState(const QString &state, const QString &name="")
Definition: mythuibuttonlist.cpp:3462
MusicPlayer::previous
void previous(void)
Definition: musicplayer.cpp:471
lyricsview.h
MythMenu
Definition: mythdialogbox.h:98
MusicPlayer::SHUFFLE_INTELLIGENT
@ SHUFFLE_INTELLIGENT
Definition: musicplayer.h:177
MythUIText
All purpose text widget, displays a text string.
Definition: mythuitext.h:28
MusicCommon::updateShuffleMode
void updateShuffleMode(bool updateUIList=false)
Definition: musiccommon.cpp:322
MythScreenType::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythscreentype.cpp:402
MusicPlayer::decSpeed
void decSpeed()
Definition: musicplayer.cpp:1357
MusicCommon::showExitMenu
void showExitMenu(void)
Definition: musiccommon.cpp:2375
MusicPlayer::activePlaylistChanged
void activePlaylistChanged(int trackID, bool deleted)
Definition: musicplayer.cpp:1458
MythMusicVolumeDialog::~MythMusicVolumeDialog
~MythMusicVolumeDialog(void) override
Definition: musiccommon.cpp:2774
MusicPlayer::setRepeatMode
void setRepeatMode(RepeatMode mode)
Definition: musicplayer.h:192
MusicMetadata::decRating
void decRating()
Definition: musicmetadata.cpp:1183
mythcorecontext.h
MythMusicVolumeDialog::updateDisplay
void updateDisplay(void)
Definition: musiccommon.cpp:2855
mythuitextedit.h
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:701
MythUIButtonListItem::SetImage
void SetImage(MythImage *image, const QString &name="")
Sets an image directly, should only be used in special circumstances since it bypasses the cache.
Definition: mythuibuttonlist.cpp:3479
MusicCommon::searchButtonList
void searchButtonList(void)
Definition: musiccommon.cpp:2252
FUNC_MUSIC
@ FUNC_MUSIC
Definition: lcddevice.h:160
MusicCommon::cycleVisualizer
void cycleVisualizer(void)
Definition: musiccommon.cpp:1035
constants.h
DialogCompletionEvent
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:40
audiooutput.h
MusicPlayer::getSpeed
float getSpeed() const
Definition: musicplayer.h:99
MusicCommon::showSpeed
static void showSpeed(bool show)
Definition: musiccommon.cpp:1010
MythUIText::SetTextFromMap
void SetTextFromMap(const InfoMap &map)
Definition: mythuitext.cpp:138
Playlist::getStats
void getStats(uint *trackCount, std::chrono::seconds *totalLength, uint currentTrack=0, std::chrono::seconds *playedLength=nullptr) const
Definition: playlist.cpp:501
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
LCD::MUSIC_REPEAT_TRACK
@ MUSIC_REPEAT_TRACK
Definition: lcddevice.h:186
MusicPlayer::isMuted
bool isMuted(void) const
Definition: musicplayer.h:89
MythUIType::SetVisible
virtual void SetVisible(bool visible)
Definition: mythuitype.cpp:1105
MusicCommon::m_movingTrack
bool m_movingTrack
Definition: musiccommon.h:153
DialogCompletionEvent::kEventType
static const Type kEventType
Definition: mythdialogbox.h:56
MythUIButtonList::Reset
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuibuttonlist.cpp:116
MusicCommon::changeVolume
void changeVolume(bool up) const
Definition: musiccommon.cpp:920
MusicCommon::startVisualizer
void startVisualizer(void)
Definition: musiccommon.cpp:1065
mainvisual.h
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
MusicCommon::m_playlistPlayedTime
std::chrono::seconds m_playlistPlayedTime
Definition: musiccommon.h:162
MThread::isRunning
bool isRunning(void) const
Definition: mthread.cpp:263
visualizerview.h
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1581
MusicPlayer::setAllowRestorePos
void setAllowRestorePos(bool allow)
Definition: musicplayer.h:154
build_compdb.action
action
Definition: build_compdb.py:9
MusicCommon::m_playedTracksList
MythUIButtonList * m_playedTracksList
Definition: musiccommon.h:206
MusicCommon::pause
static void pause(void)
Definition: musiccommon.cpp:1110
MusicPlayerEvent::kTrackRemovedEvent
static const Type kTrackRemovedEvent
Definition: musicplayer.h:42
MusicCommon::stop
void stop(void)
Definition: musiccommon.cpp:1115
MusicPlayer::play
void play(void)
Definition: musicplayer.cpp:318
MythScreenType::Exiting
void Exiting()
LCD::switchToMusic
void switchToMusic(const QString &artist, const QString &album, const QString &track)
Definition: lcddevice.cpp:572
mythuibutton.h
PlaylistOptions::playPLOption
PlayPLOption playPLOption
Definition: playlist.h:40
MusicPlayer::restorePosition
void restorePosition(void)
Definition: musicplayer.cpp:1096
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:322
MusicData::m_all_music
AllMusic * m_all_music
Definition: musicdata.h:52
MusicCommon::byAlbum
void byAlbum(void)
Definition: musiccommon.cpp:2555
PL_REPLACE
@ PL_REPLACE
Definition: playlist.h:24
MusicPlayerEvent::kTrackAddedEvent
static const Type kTrackAddedEvent
Definition: musicplayer.h:41
MusicCommon::MusicCommon
MusicCommon(MythScreenStack *parent, MythScreenType *parentScreen, const QString &name)
Definition: musiccommon.cpp:46
MV_SEARCH
@ MV_SEARCH
Definition: musiccommon.h:38
MV_VISUALIZER
@ MV_VISUALIZER
Definition: musiccommon.h:37
MusicMetadata::Rating
int Rating() const
Definition: musicmetadata.h:238
MythUIButtonTree::ShowSearchDialog
void ShowSearchDialog(void)
Definition: mythuibuttontree.cpp:361
MusicCommon::updateUIPlaylist
void updateUIPlaylist(void)
Definition: musiccommon.cpp:2101
MythThemedMenuState::Create
bool Create(void) override
Definition: myththemedmenu.cpp:35
MusicPlayerEvent::kVolumeChangeEvent
static const Type kVolumeChangeEvent
Definition: musicplayer.h:40
Playlist::fillSongsFromSonglist
void fillSongsFromSonglist(const QString &songList)
Definition: playlist.cpp:641
MusicMetadata::incRating
void incRating()
Definition: musicmetadata.cpp:1192
MythUIButtonListItem::GetImageFilename
QString GetImageFilename(const QString &name="") const
Definition: mythuibuttonlist.cpp:3573
Decoder::lock
virtual void lock(void)
Definition: decoder.h:85
Playlist::removeAllTracks
void removeAllTracks(void)
Definition: playlist.cpp:89
MusicPlayer::stop
void stop(bool stopAll=false)
Definition: musicplayer.cpp:250
Playlist::getID
int getID(void) const
Definition: playlist.h:111
OutputEvent::kBuffering
static const Type kBuffering
Definition: output.h:64
MusicCommon::m_volumeText
MythUIText * m_volumeText
Definition: musiccommon.h:191
playlist.h
MythTextInputDialog
Dialog prompting the user to enter a text string.
Definition: mythdialogbox.h:313
LCD::MUSIC_SHUFFLE_RAND
@ MUSIC_SHUFFLE_RAND
Definition: lcddevice.h:192
lcddevice.h
mythuicheckbox.h
MusicPlayer::getBufferStatus
void getBufferStatus(int *bufferAvailable, int *bufferSize) const
Definition: musicplayer.cpp:966
MythUIImage::SetFilename
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
Definition: mythuiimage.cpp:677
MythUIButtonList::ShowSearchDialog
void ShowSearchDialog(void)
Definition: mythuibuttonlist.cpp:3149
MusicCommon::m_shuffleState
MythUIStateType * m_shuffleState
Definition: musiccommon.h:178
MusicPlayer::setPlayNow
static void setPlayNow(bool PlayNow)
whether we prefer Play Now over Add Tracks
Definition: musicplayer.cpp:226
MythUIButtonList
List widget, displays list items in a variety of themeable arrangements and can trigger signals when ...
Definition: mythuibuttonlist.h:191
MusicCommon::m_visualText
MythUIText * m_visualText
Definition: musiccommon.h:175
build_compdb.filename
filename
Definition: build_compdb.py:21
Decoder::seek
virtual void seek(double)=0
Playlist::fillSonglistFromList
int fillSonglistFromList(const QList< int > &songList, bool removeDuplicates, InsertPLOption insertOption, int currentTrackID)
Definition: playlist.cpp:785
MV_MINIPLAYER
@ MV_MINIPLAYER
Definition: musiccommon.h:43
MusicCommon::m_noTracksText
MythUIText * m_noTracksText
Definition: musiccommon.h:176
MusicPlayer::getVolume
uint getVolume(void) const
Definition: musicplayer.cpp:1426
MusicCommon::m_parentScreen
MythScreenType * m_parentScreen
Definition: musiccommon.h:140
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
MythUIButtonListItem::MoveUpDown
bool MoveUpDown(bool flag)
Definition: mythuibuttonlist.cpp:3720
MusicCommon::seek
void seek(std::chrono::seconds pos)
Definition: musiccommon.cpp:1161
MusicCommon::restorePosition
bool restorePosition(int trackID)
Definition: musiccommon.cpp:2726
MusicPlayer::SHUFFLE_ALBUM
@ SHUFFLE_ALBUM
Definition: musicplayer.h:178
MusicCommon::m_randomVisualizer
bool m_randomVisualizer
Definition: musiccommon.h:147
MythRandomStd::MythRandom
uint32_t MythRandom()
generate 32 random bits
Definition: mythrandom.h:20
SearchView
Definition: searchview.h:18
AudioOutput::ToggleUpmix
virtual bool ToggleUpmix(void)
Definition: audiooutput.h:158
MusicCommon::customEvent
void customEvent(QEvent *event) override
Definition: musiccommon.cpp:1232
MusicCommon::m_controlVolume
bool m_controlVolume
Definition: musiccommon.h:155
TrackInfoDialog::Create
bool Create(void) override
Definition: musiccommon.cpp:2874
MusicCommon::m_nextButton
MythUIButton * m_nextButton
Definition: musiccommon.h:201
LCD
Definition: lcddevice.h:169
MusicMetadata::Year
int Year() const
Definition: musicmetadata.h:195
MythUIStateType
This widget is used for grouping other widgets for display when a particular named state is called....
Definition: mythuistatetype.h:22
AudioOutput::IsPaused
virtual bool IsPaused(void) const =0
MythMusicVolumeDialog::decreaseVolume
void decreaseVolume(void)
Definition: musiccommon.cpp:2843
MusicPlayer::addListener
void addListener(QObject *listener)
Definition: musicplayer.cpp:146
MusicCommon::toggleUpmix
static void toggleUpmix(void)
Definition: musiccommon.cpp:954
MythUIStateType::DisplayState
bool DisplayState(const QString &name)
Definition: mythuistatetype.cpp:84
OutputEvent::kPaused
static const Type kPaused
Definition: output.h:66
decoder.h
MusicPlayer::REPEAT_OFF
@ REPEAT_OFF
Definition: musicplayer.h:169
MusicCommon::ShowMenu
void ShowMenu(void) override
Definition: musiccommon.cpp:2263
uint
unsigned int uint
Definition: freesurround.h:24
MV_VISUALIZERINFO
@ MV_VISUALIZERINFO
Definition: musiccommon.h:44
AudioOutput::SetTimecode
virtual void SetTimecode(std::chrono::milliseconds timecode)=0
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:904
MythMusicVolumeDialog::m_volProgress
MythUIProgressBar * m_volProgress
Definition: musiccommon.h:233
MusicPlayer::SHUFFLE_RANDOM
@ SHUFFLE_RANDOM
Definition: musicplayer.h:176
MusicPlayerEvent::kAlbumArtChangedEvent
static const Type kAlbumArtChangedEvent
Definition: musicplayer.h:47
MusicCommon::allTracks
void allTracks(void)
Definition: musiccommon.cpp:2518
MusicPlayer::moveTrackUpDown
void moveTrackUpDown(bool moveUp, int whichTrack)
Definition: musicplayer.cpp:1045