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