12#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
13#include <QtSystemDetection>
15#include <QCoreApplication>
22#include "libmythbase/mythconfig.h"
33#elif defined(Q_OS_WINDOWS)
39static const QString
sLocation = QObject::tr(
"Media Monitor");
54 QDateTime now(QDateTime::currentDateTimeUtc());
63 LOG(VB_GENERAL, LOG_INFO,
"Restarting LIRC handler");
85#elif defined(Q_OS_WINDOWS)
116 LOG(VB_MEDIA, LOG_INFO,
117 QString(
"MediaMonitor::setSpeed(%1) - Cannot find/create CDROM?")
124 QString str =
d->getVolumeID();
128 str =
d->getDeviceModel();
131 str +=
" (" +
d->getDevicePath() +
')';
133 str =
d->getDevicePath();
151 QList <MythMediaDevice *> drives;
159 if (showUsable && !dev->isUsable())
162 if (QString(
typeid(*dev).name()).contains(
"MythCDROM") ||
163 (showMounted && dev->isMounted(
false)))
181 QList <MythMediaDevice *> drives =
GetRemovable(showMounted,
184 if (drives.count() == 0)
186 QString msg =
"MediaMonitor::selectDrivePopup() - no removable devices";
188 LOG(VB_MEDIA, LOG_INFO, msg);
192 if (drives.count() == 1)
194 LOG(VB_MEDIA, LOG_INFO,
195 "MediaMonitor::selectDrivePopup(" + label +
196 ") - One suitable device");
197 return drives.front();
210 while (btnIndex < -1)
220 for (
auto *drive : std::as_const(drives))
221 dlg->AddButton(
DevName(drive));
223 dlg->AddButton(tr(
"Cancel"));
230 &block, [&](
const QString& ,
int result) { block.exit(result); });
233 btnIndex = block.exec();
237 if (btnIndex < 0 || btnIndex >= drives.size())
242 return drives.at(btnIndex);
256 bool canceled {
false };
258 selectDrivePopup(tr(
"Select removable media to eject or insert"), canceled,
true);
288 LOG(VB_MEDIA, LOG_INFO,
289 QString(
"Disk %1's tray is OPEN. Closing tray").arg(dev));
294 QObject::tr(
"Unable to open or close the empty drive %1");
296 QObject::tr(
"You may have to use the eject button under its tray");
304 LOG(VB_MEDIA, LOG_INFO,
305 QString(
"Disk %1 is mounted? Unmounting").arg(dev));
318 LOG(VB_MEDIA, LOG_INFO,
319 QString(
"Unlocking disk %1, then ejecting").arg(dev));
344 m_monitorPollingInterval(interval),
345 m_allowEject(allowEject)
350 if (!ignore.isEmpty())
355 LOG(VB_MEDIA, LOG_NOTICE,
"Creating MediaMonitor");
356 LOG(VB_MEDIA, LOG_INFO,
"IgnoreDevices=" + ignore);
359 QStringList symlinked;
360 for (
const auto & ignored : std::as_const(
m_ignoreList))
362 if (
auto fi = QFileInfo(ignored); fi.isSymLink())
367 LOG(VB_MEDIA, LOG_INFO, QString(
"Also ignoring %1 (symlinked from %2)")
368 .arg(target, ignored));
384 QObject::deleteLater();
399 QList<MythMediaDevice*>::iterator it;
402 if ((*it)->getDevicePath() == dev)
410 (*it)->deleteLater();
438 QList<MythMediaDevice*>::iterator itr =
m_devices.begin();
457 LOG(VB_MEDIA, LOG_NOTICE,
"MediaMonitor disabled by user setting.");
464 qRegisterMetaType<MythMediaStatus>(
"MythMediaStatus");
466 LOG(VB_MEDIA, LOG_NOTICE,
"Starting MediaMonitor");
480 LOG(VB_MEDIA, LOG_NOTICE,
"Stopping MediaMonitor");
484 LOG(VB_MEDIA, LOG_NOTICE,
"Stopped MediaMonitor");
527 pMedia->deleteLater();
541 for (
auto *dev : std::as_const(
m_devices))
543 if (dev->isSameDevice(path) &&
577 pMedia =
MythCDROM::get(
nullptr, devPath.toLatin1(),
true,
false);
581 LOG(VB_MEDIA, LOG_INFO,
582 "MediaMonitor::GetMountPath() - failed");
612 QList<MythMediaDevice*> medias;
614 for (
auto *dev : std::as_const(
m_devices))
616 if ((dev->getMediaType() & mediatypes) &&
621 medias.push_back(dev);
648 const QString &description,
651 const QString &extensions)
655 MHData mhd = { callback, mediaType, destination, description };
658 if (!extensions.isEmpty())
659 msg += QString(
", ext(%1)").arg(extensions);
661 LOG(VB_MEDIA, LOG_INFO,
662 "Registering '" + destination +
"' as a media handler for " +
667 if (!extensions.isEmpty())
672 LOG(VB_GENERAL, LOG_INFO,
673 destination +
" is already registered as a media handler.");
687 QMap<QString, MHData>::Iterator itr =
m_handlerMap.begin();
691 if (((*itr).MythMediaType & (
int)pMedia->
getMediaType()))
693 LOG(VB_GENERAL, LOG_NOTICE,
694 QString(
"Found a handler for %1 - '%2'")
703 LOG(VB_MEDIA, LOG_INFO,
"No media handler found for event type");
712 handlers.at(selected).callback(pMedia, forcePlayback);
727 QString msg = QString(
" (%1, %2 -> %3)")
742 LOG(VB_MEDIA, LOG_INFO,
"Posting MediaEvent" + msg);
753 LOG(VB_MEDIA, LOG_INFO,
754 "Media status changed, but not sending event" + msg);
774 LOG(VB_MEDIA, LOG_INFO,
781 LOG(VB_MEDIA, LOG_DEBUG,
784 LOG(VB_MEDIA, LOG_DEBUG,
803 LOG(VB_GENERAL, LOG_ALERT,
804 "MediaMonitor::eventFilter() couldn't cast event");
811 LOG(VB_GENERAL, LOG_ALERT,
812 "MediaMonitor::eventFilter() got a bad media event?");
823 QMap<QString, MHData>::Iterator itr =
m_handlerMap.begin();
828 (*itr).callback(pDev,
false);
837 return QObject::eventFilter(obj, event);
853 const QString &label,
854 const char *hardCodedDefault)
858 LOG(VB_MEDIA, LOG_DEBUG,
859 QString(
"MediaMonitor::defaultDevice(%1,..,%2) dbSetting='%3'")
860 .arg(dbSetting, hardCodedDefault, device));
863 if (device.isEmpty() || device ==
"default")
865 device = hardCodedDefault;
872 bool canceled {
false };
883 device =
d->getDevicePath();
889 LOG(VB_MEDIA, LOG_DEBUG,
890 "MediaMonitor::defaultDevice() returning " + device);
951 for (
const auto *dev : std::as_const(
m_devices))
954 QString model = dev->getDeviceModel();
955 const QString& path = dev->getDevicePath();
956 const QString& real = dev->getRealDevice();
959 devStr += path +
"->";
964 devStr +=
" (" + model +
")";
969 return list.join(
", ");
985 LOG(VB_MEDIA, LOG_INFO,
"CD/DVD Monitor isn't enabled.");
987 LOG(VB_MEDIA, LOG_INFO,
"Trying Linux 'eject -T' command");
989#elif defined(Q_OS_DARWIN)
991 LOG(VB_MEDIA, LOG_INFO,
"Trying 'diskutil eject " + def);
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
QDateTime m_lastCheckTime
QPointer< MediaMonitor > m_monitor
static MythCDROM * get(QObject *par, const QString &devicePath, bool SuperMount, bool AllowEject)
void setDeviceSpeed(const char *devicePath, int speed) override
QString GetSetting(const QString &key, const QString &defaultval="")
bool GetBoolSetting(const QString &key, bool defaultval=false)
Basic menu dialog, message and a list of options.
void Closed(QString, int)
MythScreenStack * GetMainStack()
void RestartInputHandlers()
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
static QList< GameHandler * > * handlers
static const iso6937table * d
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
bool HasMythMainWindow(void)
MythMainWindow * GetMythMainWindow(void)
QString getSymlinkTarget(const QString &start_file, QStringList *intermediaries, unsigned maxLinks)
void ShowNotificationError(const QString &msg, const QString &from, const QString &detail, const VNMask visibility, const MythNotification::Priority priority)
convenience utility to display error message as notification
void ShowNotification(const QString &msg, const QString &from, const QString &detail, const VNMask visibility, const MythNotification::Priority priority)
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
Stores details of media handlers.