10#include <QScopedPointer>
21#include <libmythbase/mythversion.h>
58static QString chooseCD(
void)
77 QString sql =
"SELECT DISTINCT hostname "
79 "WHERE groupname = 'Music'";
88 hostList.append(query.
value(0).toString());
92 if (hostList.isEmpty())
94 ShowOkPopup(QCoreApplication::translate(
"(MythMusicMain)",
95 "No directories found in the 'Music' storage group. "
96 "Please run mythtv-setup on the backend machine to add one."));
102 sql =
"SELECT DISTINCT hostname "
104 "WHERE groupname = 'MusicArt'";
113 hostList.append(query.
value(0).toString());
117 if (hostList.isEmpty())
119 ShowOkPopup(QCoreApplication::translate(
"(MythMusicMain)",
120 "No directories found in the 'MusicArt' storage group. "
121 "Please run mythtv-setup on the backend machine to add one."));
132 bool foundMusic =
false;
133 if (count_query.
exec(
"SELECT COUNT(*) FROM music_songs;"))
135 if(count_query.
next() &&
136 0 != count_query.
value(0).toInt())
144 ShowOkPopup(QCoreApplication::translate(
"(MythMusicMain)",
145 "No music has been found.\n"
146 "Please select 'Scan For New Music' "
147 "to perform a scan for music."));
176 auto *view =
new StreamView(mainStack,
nullptr);
212 auto *rip =
new Ripper(mainStack, chooseCD());
219 Qt::QueuedConnection);
227 ShowOkPopup(QCoreApplication::translate(
"(MythMusicMain)",
228 "MythMusic hasn't been built with libcdio "
229 "support so ripping CDs is not possible"));
238 LOG(VB_GENERAL, LOG_INFO,
"Scanning for music files");
254 if (import->Create())
259 Qt::QueuedConnection);
273 QString sel = selection.toLower();
274 if (sel ==
"music_create_playlist")
278 else if (sel ==
"music_play")
282 else if (sel ==
"stream_play")
286 else if (sel ==
"music_rip")
290 else if (sel ==
"music_import")
294 else if (sel ==
"settings_scan")
298 else if (sel ==
"settings_general")
308 else if (sel ==
"settings_player")
318 else if (sel ==
"settings_rating")
328 else if (sel ==
"settings_visualization")
339 else if (sel ==
"settings_import")
368 auto *
menu = qobject_cast<MythThemedMenu *>(parentObject);
370 if (
menu &&
menu->objectName() ==
"mainmenu")
376 parentObject = parentObject->parent();
390 if (diag->foundTheme())
399 LOG(VB_GENERAL, LOG_ERR, QString(
"Couldn't find menu %1 or theme %2")
433 auto *rip =
new Ripper(mainStack, chooseCD());
447 Qt::QueuedConnection);
464 filt.replace(
".",
"*.");
465 return filt.split(
'|');
468static QStringList
BuildFileList(
const QString &dir,
const QStringList &filters)
476 d.setNameFilters(filters);
477 d.setFilter(QDir::Files | QDir::AllDirs |
478 QDir::NoSymLinks | QDir::Readable |
479 QDir::NoDotAndDotDot);
480 d.setSorting(QDir::Name | QDir::DirsLast);
482 QFileInfoList list =
d.entryInfoList();
486 for (
const auto & fi : std::as_const(list))
491 QCoreApplication::processEvents();
495 ret << fi.absoluteFilePath();
503 static QString s_mountPath;
513 LOG(VB_MEDIA, LOG_INFO, QString(
514 "MythMusic: '%1' unmounted, clearing data").arg(cd->
getVolumeID()));
536 LOG(VB_MEDIA, LOG_NOTICE, QString(
"MythMusic: '%1' mounted on '%2'")
556 QString message = QCoreApplication::translate(
"(MythMusicMain)",
557 "Searching for music files...");
558 auto *busy =
new MythUIBusyDialog( message, popupStack,
"musicscanbusydialog");
571 LOG(VB_MEDIA, LOG_INFO, QString(
"MythMusic: %1 music files found")
572 .arg(trackList.count()));
577 if (trackList.isEmpty())
580 message = QCoreApplication::translate(
"(MythMusicMain)",
"Loading music tracks");
582 "scalingprogressdialog");
586 progress->SetTotal(trackList.count());
596 for (
const auto &
file : std::as_const(trackList))
601 meta->setTrack(++track);
607 QCoreApplication::processEvents();
610 LOG(VB_MEDIA, LOG_INFO, QString(
"MythMusic: %1 tracks scanned").arg(track));
621 songList.reserve(tracks);
622 for (track = 1; track <= tracks; track++)
626 songList.append(mdata->
ID());
628 if (songList.isEmpty())
656 LOG(VB_MEDIA, LOG_NOTICE,
"Got a CD media changed event");
670 LOG(VB_MEDIA, LOG_INFO,
"MythMusic: Storing CD device " +
gCDdevice);
674 LOG(VB_MEDIA, LOG_INFO,
"Device is not usable clearing cd data");
704 QCoreApplication::processEvents();
705 std::this_thread::sleep_for(50ms);
713 auto *decoder =
new CdDecoder(
"cda",
nullptr,
nullptr);
714 decoder->setDevice(newDevice);
716 int tracks = decoder->getNumTracks();
717 bool setTitle =
false;
719 for (
int trackNo = 1; trackNo <= tracks; trackNo++)
729 QString parenttitle =
" ";
733 parenttitle +=
" ~ ";
736 if (track->
Album().length() > 0)
738 parenttitle += track->
Album();
742 parenttitle =
" " + QCoreApplication::translate(
"(MythMusicMain)",
744 LOG(VB_GENERAL, LOG_INFO,
"Couldn't find your "
745 " CD. It may not be in the freedb database.\n"
746 " More likely, however, is that you need to delete\n"
747 " ~/.cddb and ~/.cdserverrc and restart MythMusic.");
775 songList.append(mdata->
ID());
778 if (!songList.isEmpty())
804 LOG(VB_GENERAL, LOG_NOTICE,
"MythMusic got a media changed event"
805 "but cdio support is not compiled in");
811 REG_JUMP(QT_TRANSLATE_NOOP(
"MythControls",
"Play music"),
813 REG_JUMP(QT_TRANSLATE_NOOP(
"MythControls",
"Select music playlists"),
815 REG_JUMP(QT_TRANSLATE_NOOP(
"MythControls",
"Play radio stream"),
817 REG_JUMP(QT_TRANSLATE_NOOP(
"MythControls",
"Rip CD"),
819 REG_JUMP(QT_TRANSLATE_NOOP(
"MythControls",
"Scan music"),
821 REG_JUMPEX(QT_TRANSLATE_NOOP(
"MythControls",
"Show Music Miniplayer"),
824 REG_KEY(
"Music",
"NEXTTRACK", QT_TRANSLATE_NOOP(
"MythControls",
825 "Move to the next track"),
">,.,Z,End,Media Next");
826 REG_KEY(
"Music",
"PREVTRACK", QT_TRANSLATE_NOOP(
"MythControls",
827 "Move to the previous track"),
",,<,Q,Home,Media Previous");
828 REG_KEY(
"Music",
"FFWD", QT_TRANSLATE_NOOP(
"MythControls",
829 "Fast forward"),
"PgDown,Ctrl+F,Media Fast Forward");
830 REG_KEY(
"Music",
"RWND", QT_TRANSLATE_NOOP(
"MythControls",
831 "Rewind"),
"PgUp,Ctrl+B,Media Rewind");
832 REG_KEY(
"Music",
"PAUSE", QT_TRANSLATE_NOOP(
"MythControls",
833 "Pause/Start playback"),
"P,Media Play");
834 REG_KEY(
"Music",
"PLAY", QT_TRANSLATE_NOOP(
"MythControls",
835 "Start playback"),
"");
836 REG_KEY(
"Music",
"STOP", QT_TRANSLATE_NOOP(
"MythControls",
837 "Stop playback"),
"O,Media Stop");
838 REG_KEY(
"Music",
"VOLUMEDOWN", QT_TRANSLATE_NOOP(
"MythControls",
839 "Volume down"),
"[,{,F10,Volume Down");
840 REG_KEY(
"Music",
"VOLUMEUP", QT_TRANSLATE_NOOP(
"MythControls",
841 "Volume up"),
"],},F11,Volume Up");
842 REG_KEY(
"Music",
"MUTE", QT_TRANSLATE_NOOP(
"MythControls",
843 "Mute"),
"|,\\,F9,Volume Mute");
844 REG_KEY(
"Music",
"TOGGLEUPMIX",QT_TRANSLATE_NOOP(
"MythControls",
845 "Toggle audio upmixer"),
"Ctrl+U");
846 REG_KEY(
"Music",
"CYCLEVIS", QT_TRANSLATE_NOOP(
"MythControls",
847 "Cycle visualizer mode"),
"6");
848 REG_KEY(
"Music",
"BLANKSCR", QT_TRANSLATE_NOOP(
"MythControls",
849 "Blank screen"),
"5");
850 REG_KEY(
"Music",
"THMBUP", QT_TRANSLATE_NOOP(
"MythControls",
851 "Increase rating"),
"9");
852 REG_KEY(
"Music",
"THMBDOWN", QT_TRANSLATE_NOOP(
"MythControls",
853 "Decrease rating"),
"7");
854 REG_KEY(
"Music",
"REFRESH", QT_TRANSLATE_NOOP(
"MythControls",
855 "Refresh music tree"),
"8");
856 REG_KEY(
"Music",
"SPEEDUP", QT_TRANSLATE_NOOP(
"MythControls",
857 "Increase Play Speed"),
"W,3");
858 REG_KEY(
"Music",
"SPEEDDOWN", QT_TRANSLATE_NOOP(
"MythControls",
859 "Decrease Play Speed"),
"X,1");
860 REG_KEY(
"Music",
"MARK", QT_TRANSLATE_NOOP(
"MythControls",
861 "Toggle track selection"),
"T");
862 REG_KEY(
"Music",
"TOGGLESHUFFLE", QT_TRANSLATE_NOOP(
"MythControls",
863 "Toggle shuffle mode"),
"");
864 REG_KEY(
"Music",
"TOGGLEREPEAT", QT_TRANSLATE_NOOP(
"MythControls",
865 "Toggle repeat mode"),
"");
866 REG_KEY(
"Music",
"TOGGLELAST", QT_TRANSLATE_NOOP(
"MythControls",
867 "Switch to previous radio stream"),
"");
870 REG_KEY(
"Music",
"SWITCHTOPLAYLIST", QT_TRANSLATE_NOOP(
"MythControls",
871 "Switch to the current playlist view"),
"");
872 REG_KEY(
"Music",
"SWITCHTOPLAYLISTEDITORTREE", QT_TRANSLATE_NOOP(
"MythControls",
873 "Switch to the playlist editor tree view"),
"");
874 REG_KEY(
"Music",
"SWITCHTOPLAYLISTEDITORGALLERY", QT_TRANSLATE_NOOP(
"MythControls",
875 "Switch to the playlist editor gallery view"),
"");
876 REG_KEY(
"Music",
"SWITCHTOSEARCH", QT_TRANSLATE_NOOP(
"MythControls",
877 "Switch to the search view"),
"");
878 REG_KEY(
"Music",
"SWITCHTOVISUALISER", QT_TRANSLATE_NOOP(
"MythControls",
879 "Switch to the fullscreen visualiser view"),
"");
880 REG_KEY(
"Music",
"SWITCHTORADIO", QT_TRANSLATE_NOOP(
"MythControls",
881 "Switch to the radio stream view"),
"");
887 filt.replace(
'|',
',');
897 MYTH_BINARY_VERSION))
906 LOG(VB_GENERAL, LOG_ERR,
907 "Couldn't upgrade music database schema, exiting.");
922 return runMenu(
"musicmenu.xml");
927 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()