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