10#include <QScopedPointer>
21#include <libmythbase/mythversion.h>
58static QString chooseCD(
void)
77 QString sql =
"SELECT DISTINCT hostname "
79 "WHERE groupname = 'Music'";
86 hostList.append(query.
value(0).toString());
90 if (hostList.isEmpty())
92 ShowOkPopup(QCoreApplication::translate(
"(MythMusicMain)",
93 "No directories found in the 'Music' storage group. "
94 "Please run mythtv-setup on the backend machine to add one."));
100 sql =
"SELECT DISTINCT hostname "
102 "WHERE groupname = 'MusicArt'";
109 hostList.append(query.
value(0).toString());
113 if (hostList.isEmpty())
115 ShowOkPopup(QCoreApplication::translate(
"(MythMusicMain)",
116 "No directories found in the 'MusicArt' storage group. "
117 "Please run mythtv-setup on the backend machine to add one."));
128 bool foundMusic =
false;
129 if (count_query.
exec(
"SELECT COUNT(*) FROM music_songs;"))
131 if(count_query.
next() &&
132 0 != count_query.
value(0).toInt())
140 ShowOkPopup(QCoreApplication::translate(
"(MythMusicMain)",
141 "No music has been found.\n"
142 "Please select 'Scan For New Music' "
143 "to perform a scan for music."));
172 auto *view =
new StreamView(mainStack,
nullptr);
208 auto *rip =
new Ripper(mainStack, chooseCD());
215 Qt::QueuedConnection);
223 ShowOkPopup(QCoreApplication::translate(
"(MythMusicMain)",
224 "MythMusic hasn't been built with libcdio "
225 "support so ripping CDs is not possible"));
234 LOG(VB_GENERAL, LOG_INFO,
"Scanning for music files");
250 if (import->Create())
255 Qt::QueuedConnection);
269 QString sel = selection.toLower();
270 if (sel ==
"music_create_playlist")
272 else if (sel ==
"music_play")
274 else if (sel ==
"stream_play")
276 else if (sel ==
"music_rip")
280 else if (sel ==
"music_import")
284 else if (sel ==
"settings_scan")
288 else if (sel ==
"settings_general")
298 else if (sel ==
"settings_player")
308 else if (sel ==
"settings_rating")
318 else if (sel ==
"settings_visualization")
329 else if (sel ==
"settings_import")
358 auto *
menu = qobject_cast<MythThemedMenu *>(parentObject);
360 if (
menu &&
menu->objectName() ==
"mainmenu")
366 parentObject = parentObject->parent();
380 if (diag->foundTheme())
389 LOG(VB_GENERAL, LOG_ERR, QString(
"Couldn't find menu %1 or theme %2")
423 auto *rip =
new Ripper(mainStack, chooseCD());
435 Qt::QueuedConnection);
452 filt.replace(
".",
"*.");
453 return filt.split(
'|');
456static QStringList
BuildFileList(
const QString &dir,
const QStringList &filters)
464 d.setNameFilters(filters);
465 d.setFilter(QDir::Files | QDir::AllDirs |
466 QDir::NoSymLinks | QDir::Readable |
467 QDir::NoDotAndDotDot);
468 d.setSorting(QDir::Name | QDir::DirsLast);
470 QFileInfoList list =
d.entryInfoList();
474 for (
const auto & fi : std::as_const(list))
479 QCoreApplication::processEvents();
483 ret << fi.absoluteFilePath();
491 static QString s_mountPath;
501 LOG(VB_MEDIA, LOG_INFO, QString(
502 "MythMusic: '%1' unmounted, clearing data").arg(cd->
getVolumeID()));
524 LOG(VB_MEDIA, LOG_NOTICE, QString(
"MythMusic: '%1' mounted on '%2'")
544 QString message = QCoreApplication::translate(
"(MythMusicMain)",
545 "Searching for music files...");
546 auto *busy =
new MythUIBusyDialog( message, popupStack,
"musicscanbusydialog");
557 LOG(VB_MEDIA, LOG_INFO, QString(
"MythMusic: %1 music files found")
558 .arg(trackList.count()));
563 if (trackList.isEmpty())
566 message = QCoreApplication::translate(
"(MythMusicMain)",
"Loading music tracks");
568 "scalingprogressdialog");
572 progress->SetTotal(trackList.count());
582 for (
const auto &
file : std::as_const(trackList))
587 meta->setTrack(++track);
593 QCoreApplication::processEvents();
596 LOG(VB_MEDIA, LOG_INFO, QString(
"MythMusic: %1 tracks scanned").arg(track));
607 for (track = 1; track <= tracks; track++)
611 songList.append(mdata->
ID());
613 if (songList.isEmpty())
641 LOG(VB_MEDIA, LOG_NOTICE,
"Got a CD media changed event");
655 LOG(VB_MEDIA, LOG_INFO,
"MythMusic: Storing CD device " +
gCDdevice);
659 LOG(VB_MEDIA, LOG_INFO,
"Device is not usable clearing cd data");
689 QCoreApplication::processEvents();
698 auto *decoder =
new CdDecoder(
"cda",
nullptr,
nullptr);
699 decoder->setDevice(newDevice);
701 int tracks = decoder->getNumTracks();
702 bool setTitle =
false;
704 for (
int trackNo = 1; trackNo <= tracks; trackNo++)
714 QString parenttitle =
" ";
718 parenttitle +=
" ~ ";
721 if (track->
Album().length() > 0)
722 parenttitle += track->
Album();
725 parenttitle =
" " + QCoreApplication::translate(
"(MythMusicMain)",
727 LOG(VB_GENERAL, LOG_INFO,
"Couldn't find your "
728 " CD. It may not be in the freedb database.\n"
729 " More likely, however, is that you need to delete\n"
730 " ~/.cddb and ~/.cdserverrc and restart MythMusic.");
757 songList.append((mdata)->ID());
760 if (!songList.isEmpty())
786 LOG(VB_GENERAL, LOG_NOTICE,
"MythMusic got a media changed event"
787 "but cdio support is not compiled in");
793 REG_JUMP(QT_TRANSLATE_NOOP(
"MythControls",
"Play music"),
795 REG_JUMP(QT_TRANSLATE_NOOP(
"MythControls",
"Select music playlists"),
797 REG_JUMP(QT_TRANSLATE_NOOP(
"MythControls",
"Play radio stream"),
799 REG_JUMP(QT_TRANSLATE_NOOP(
"MythControls",
"Rip CD"),
801 REG_JUMP(QT_TRANSLATE_NOOP(
"MythControls",
"Scan music"),
803 REG_JUMPEX(QT_TRANSLATE_NOOP(
"MythControls",
"Show Music Miniplayer"),
806 REG_KEY(
"Music",
"NEXTTRACK", QT_TRANSLATE_NOOP(
"MythControls",
807 "Move to the next track"),
">,.,Z,End,Media Next");
808 REG_KEY(
"Music",
"PREVTRACK", QT_TRANSLATE_NOOP(
"MythControls",
809 "Move to the previous track"),
",,<,Q,Home,Media Previous");
810 REG_KEY(
"Music",
"FFWD", QT_TRANSLATE_NOOP(
"MythControls",
811 "Fast forward"),
"PgDown,Ctrl+F,Media Fast Forward");
812 REG_KEY(
"Music",
"RWND", QT_TRANSLATE_NOOP(
"MythControls",
813 "Rewind"),
"PgUp,Ctrl+B,Media Rewind");
814 REG_KEY(
"Music",
"PAUSE", QT_TRANSLATE_NOOP(
"MythControls",
815 "Pause/Start playback"),
"P,Media Play");
816 REG_KEY(
"Music",
"PLAY", QT_TRANSLATE_NOOP(
"MythControls",
817 "Start playback"),
"");
818 REG_KEY(
"Music",
"STOP", QT_TRANSLATE_NOOP(
"MythControls",
819 "Stop playback"),
"O,Media Stop");
820 REG_KEY(
"Music",
"VOLUMEDOWN", QT_TRANSLATE_NOOP(
"MythControls",
821 "Volume down"),
"[,{,F10,Volume Down");
822 REG_KEY(
"Music",
"VOLUMEUP", QT_TRANSLATE_NOOP(
"MythControls",
823 "Volume up"),
"],},F11,Volume Up");
824 REG_KEY(
"Music",
"MUTE", QT_TRANSLATE_NOOP(
"MythControls",
825 "Mute"),
"|,\\,F9,Volume Mute");
826 REG_KEY(
"Music",
"TOGGLEUPMIX",QT_TRANSLATE_NOOP(
"MythControls",
827 "Toggle audio upmixer"),
"Ctrl+U");
828 REG_KEY(
"Music",
"CYCLEVIS", QT_TRANSLATE_NOOP(
"MythControls",
829 "Cycle visualizer mode"),
"6");
830 REG_KEY(
"Music",
"BLANKSCR", QT_TRANSLATE_NOOP(
"MythControls",
831 "Blank screen"),
"5");
832 REG_KEY(
"Music",
"THMBUP", QT_TRANSLATE_NOOP(
"MythControls",
833 "Increase rating"),
"9");
834 REG_KEY(
"Music",
"THMBDOWN", QT_TRANSLATE_NOOP(
"MythControls",
835 "Decrease rating"),
"7");
836 REG_KEY(
"Music",
"REFRESH", QT_TRANSLATE_NOOP(
"MythControls",
837 "Refresh music tree"),
"8");
838 REG_KEY(
"Music",
"SPEEDUP", QT_TRANSLATE_NOOP(
"MythControls",
839 "Increase Play Speed"),
"W,3");
840 REG_KEY(
"Music",
"SPEEDDOWN", QT_TRANSLATE_NOOP(
"MythControls",
841 "Decrease Play Speed"),
"X,1");
842 REG_KEY(
"Music",
"MARK", QT_TRANSLATE_NOOP(
"MythControls",
843 "Toggle track selection"),
"T");
844 REG_KEY(
"Music",
"TOGGLESHUFFLE", QT_TRANSLATE_NOOP(
"MythControls",
845 "Toggle shuffle mode"),
"");
846 REG_KEY(
"Music",
"TOGGLEREPEAT", QT_TRANSLATE_NOOP(
"MythControls",
847 "Toggle repeat mode"),
"");
848 REG_KEY(
"Music",
"TOGGLELAST", QT_TRANSLATE_NOOP(
"MythControls",
849 "Switch to previous radio stream"),
"");
852 REG_KEY(
"Music",
"SWITCHTOPLAYLIST", QT_TRANSLATE_NOOP(
"MythControls",
853 "Switch to the current playlist view"),
"");
854 REG_KEY(
"Music",
"SWITCHTOPLAYLISTEDITORTREE", QT_TRANSLATE_NOOP(
"MythControls",
855 "Switch to the playlist editor tree view"),
"");
856 REG_KEY(
"Music",
"SWITCHTOPLAYLISTEDITORGALLERY", QT_TRANSLATE_NOOP(
"MythControls",
857 "Switch to the playlist editor gallery view"),
"");
858 REG_KEY(
"Music",
"SWITCHTOSEARCH", QT_TRANSLATE_NOOP(
"MythControls",
859 "Switch to the search view"),
"");
860 REG_KEY(
"Music",
"SWITCHTOVISUALISER", QT_TRANSLATE_NOOP(
"MythControls",
861 "Switch to the fullscreen visualiser view"),
"");
862 REG_KEY(
"Music",
"SWITCHTORADIO", QT_TRANSLATE_NOOP(
"MythControls",
863 "Switch to the radio stream view"),
"");
869 filt.replace(
'|',
',');
879 MYTH_BINARY_VERSION))
888 LOG(VB_GENERAL, LOG_ERR,
889 "Couldn't upgrade music database schema, exiting.");
904 return runMenu(
"musicmenu.xml");
909 return runMenu(
"music_settings.xml");
MusicMetadata * getCDMetadata(int m_the_track)
void addCDTrack(const MusicMetadata &the_track)
int getCDTrackCount(void) const
void save()
Check each MusicMetadata entry and save those that have changed (ratings, etc.)
void setCDTitle(const QString &a_title)
void importFinished(void)
QSqlQuery wrapper that fetches a DB connection from the connection pool.
QVariant value(int i) const
bool isActive(void) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
static void scanMusic(void)
void reloadMusic(void) const
reload music after a scan, rip or import
void loadMusic(void) const
PlaylistContainer * m_all_playlists
MusicMetadata * getCurrentMetadata(void)
get the metadata for the current track in the playlist
void showMiniPlayer(void) const
void stop(bool stopAll=false)
void activePlaylistChanged(int trackID, bool deleted)
void sendCDChangedEvent(void)
bool isPlaying(void) const
bool setCurrentTrackPos(int pos)
void ActivateSettingsCache(bool activate=true)
void SaveSetting(const QString &key, int newValue)
QString GetSetting(const QString &key, const QString &defaultval="")
static bool TestPluginVersion(const QString &name, const QString &libversion, const QString &pluginversion)
bool GetBoolSetting(const QString &key, bool defaultval=false)
static void DBError(const QString &where, const MSqlQuery &query)
MythScreenStack * GetMainStack()
MythScreenStack * GetStack(const QString &Stackname)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
virtual MythScreenType * GetTopScreen(void) const
QString RemoveCurrentLocation()
void AddCurrentLocation(const QString &Location)
Playlist * getActive(void)
void removeAllCDTracks(void)
void removeAllTracks(void)
int fillSonglistFromList(const QList< int > &songList, bool removeDuplicates, InsertPLOption insertOption, int currentTrackID)
static const iso6937table * d
bool UpgradeMusicDatabaseSchema(void)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MythMainWindow * GetMythMainWindow(void)
static void REG_JUMPEX(const QString &Destination, const QString &Description, const QString &Key, void(*Callback)(void), bool ExitToMain)
static void REG_JUMP(const QString &Destination, const QString &Description, const QString &Key, void(*Callback)(void))
static void REG_KEY(const QString &Context, const QString &Action, const QString &Description, const QString &Key)
static void handleMedia(MythMediaDevice *cd, bool forcePlayback)
static void startStreamPlayback(void)
static void showMiniPlayer(void)
int mythplugin_config(void)
static QStringList BuildFileList(const QString &dir, const QStringList &filters)
static void runScan(void)
static void(* m_callback)(void *, QString &)
static void runMusicStreamPlayback(void)
void mythplugin_destroy(void)
static void startPlayback(void)
static void startRipper(void)
static void startImport(void)
static void startDatabaseTree(void)
static void runRipCD(void)
static void handleCDMedia(MythMediaDevice *cd, bool forcePlayback)
static void runMusicPlayback(void)
static void setupKeys(void)
static int runMenu(const QString &which_menu)
static void MusicCallback(void *data, QString &selection)
static bool checkStorageGroup(void)
checks we have at least one music directory in the 'Music' storage group
static void runMusicSelection(void)
static bool checkMusicAvailable(void)
checks we have some tracks available
static QStringList GetMusicFilter()
int mythplugin_init(const char *libversion)
static void * m_callbackdata
static MythThemedMenu * menu
MythUIHelper * GetMythUI()