4#if QT_VERSION >= QT_VERSION_CHECK(6,5,0)
5#include <QtSystemDetection>
11#if defined(Q_OS_BSD4) || defined(Q_OS_WINDOWS)
14#include <sys/sysmacros.h>
22#include <QCoreApplication>
36#include "libmythbase/mythconfig.h"
66#include HDHOMERUN_HEADERFILE
71 bool _must_have_mplexid) :
72 m_initialSourceId(_initial_sourceid),
73 m_cardTypes(std::move(_card_types)),
74 m_mustHaveMplexId(_must_have_mplexid)
79 "Select a video source that is connected to one "
80 "or more capture cards. Default is the video source "
81 "selected in the Channel Editor page."
90 "SELECT DISTINCT videosource.name, videosource.sourceid "
91 "FROM capturecard, videosource";
96 "WHERE capturecard.sourceid = videosource.sourceid AND "
97 " capturecard.hostname = :HOSTNAME ";
101 querystr += QString(
" AND capturecard.cardtype in %1 ")
108 " AND channel.sourceid = videosource.sourceid "
109 " AND channel.mplexid != 32767 "
110 " AND channel.mplexid != 0 ";
121 for (; query.
next(); cnt++)
124 query.
value(1).toString());
139 m_initialSourceId(_initial_sourceid)
144 "The video source that is "
145 "selected in the Channel Editor page."
154 "SELECT DISTINCT videosource.name, videosource.sourceid "
155 "FROM capturecard, videosource "
156 "WHERE capturecard.sourceid = videosource.sourceid AND "
157 " capturecard.hostname = :HOSTNAME AND "
158 " videosource.sourceid = :SOURCEID ";
183 setLabel(QObject::tr(
"Max recordings"));
187 "Maximum number of simultaneous recordings MythTV will "
188 "attempt using this device. If set to a value other than "
189 "1, MythTV can sometimes record multiple programs on "
190 "the same multiplex or overlapping copies of the same "
191 "program on a single channel."
207 setLabel(QObject::tr(
"Schedule as group"));
211 "Schedule all virtual inputs on this device as a group. "
212 "This is more efficient than scheduling each input "
213 "individually. Additional, virtual inputs will be "
214 "automatically added as needed to fulfill the recording "
227 QString sourceidTag(
":WHERESOURCEID");
229 QString query(
"sourceid = " + sourceidTag);
238 QString sourceidTag(
":SETSOURCEID");
241 QString query(
"sourceid = " + sourceidTag +
", " +
252 QString cardidTag(
":WHERECARDID");
254 QString query(
"cardid = " + cardidTag);
263 QString cardidTag(
":SETCARDID");
266 QString query(
"cardid = " + cardidTag +
", " +
283 setLabel(QObject::tr(
"Listings grabber"));
297 QObject::tr(
"Transmitted guide only (EIT)"),
"eitonly");
309 QMutexLocker lock(&
m_lock);
317 find_grabber_proc.
Run(25s);
318 LOG(VB_GENERAL, LOG_INFO,
319 loc +
"Running 'tv_find_grabbers " +
args.join(
" ") +
"'.");
320 uint status = find_grabber_proc.
Wait();
324 QTextStream ostream(find_grabber_proc.
ReadAll());
325 while (!ostream.atEnd())
327 QString grabber_list(ostream.readLine());
328 QStringList grabber_split =
329 grabber_list.split(
"|", Qt::SkipEmptyParts);
330 QString grabber_name = grabber_split[1] +
" (xmltv)";
331 QFileInfo grabber_file(grabber_split[0]);
334 m_progList.push_back(grabber_file.fileName());
335 LOG(VB_GENERAL, LOG_DEBUG,
"Found " + grabber_split[0]);
337 LOG(VB_GENERAL, LOG_INFO, loc +
"Finished running tv_find_grabbers");
341 LOG(VB_GENERAL, LOG_ERR, loc +
"Failed to run tv_find_grabbers");
346 LOG(VB_GENERAL, LOG_INFO, loc +
"Loading results of tv_find_grabbers");
359 "UPDATE videosource "
360 "SET userid=NULL, password=NULL "
361 "WHERE xmltvgrabber NOT IN ( 'technovera' )");
368 if (name_list.size() != prog_list.size())
375 for (
uint i = 0; i < (
uint) name_list.size(); i++)
383 if (!selValue.isEmpty())
406 std::chrono::milliseconds min_val,
407 std::chrono::milliseconds max_val,
408 std::chrono::milliseconds step,
409 const QString &setting) :
411 min_val.count(), max_val.count(), step.count())
425 requires (!std::is_integral<T>())
426 {
setValueMs(duration_cast<std::chrono::milliseconds>(newSecs)); }
433 const QString &setting) :
450 setLabel(QObject::tr(
"Scan Frequency"));
451 setHelpText(QObject::tr(
"The frequency to start scanning this video source. "
452 "This is then default for 'Full Scan (Tuned)' channel scanning. "
453 "Frequency value in Hz for DVB-T/T2/C, in kHz for DVB-S/S2. "
454 "Leave at 0 if not known. "));
470 setLabel(QObject::tr(
"Network ID"));
473 setHelpText(QObject::tr(
"If your provider has asked you to configure a "
474 "specific network identifier (Network_ID), "
475 "enter it here. Leave it at -1 otherwise."));
492 setLabel(QObject::tr(
"Bouquet ID"));
493 setHelpText(QObject::tr(
"Bouquet ID for Freesat or Sky on satellite Astra-2 28.2E. "
494 "Leave this at 0 if you do not receive this satellite. "
495 "This is needed to get the Freesat and Sky channel numbers. "
496 "Value 272 selects Freesat bouquet 'England HD'. "
497 "See the MythTV Wiki https://www.mythtv.org/wiki/DVB_UK."));
515 setHelpText(QObject::tr(
"Region ID for Freesat or Sky on satellite Astra-2 28.2E. "
516 "Leave this at 0 you do not receive this satellite. "
517 "This is needed to get the Freesat and Sky channel numbers. "
518 "Value 1 selects region London. "
519 "See the MythTV Wiki https://www.mythtv.org/wiki/DVB_UK."));
536 setLabel(QObject::tr(
"Logical Channel Number Offset"));
537 setHelpText(QObject::tr(
"The offset is added to each logical channel number found "
538 "during a scan of a DVB video source. This makes it possible "
539 "to give different video sources a non-overlapping range "
540 "of channel numbers. Leave at 0 if you have only one video source "
541 "or if the video sources do not have DVB logical channel numbers."));
554 setLabel(QObject::tr(
"Channel frequency table"));
560 setHelpText(QObject::tr(
"Use default unless this source uses a "
561 "different frequency table than the system wide table "
562 "defined in the General settings."));
571 m_sourceId(_sourceid)
573 setLabel(QObject::tr(
"Channel frequency table"));
592 "WHERE sourceid = :SOURCEID");
618 LOG(VB_GENERAL, LOG_INFO,
"TransFreqTableSelector::Save(void)");
629 "UPDATE videosource "
630 "SET freqtable = :FREQTABLE "
631 "WHERE sourceid = :SOURCEID");
655 setLabel(QObject::tr(
"Perform EIT scan"));
657 "If enabled, program guide data for channels on this "
658 "source will be updated with data provided by the "
659 "channels themselves 'Over-the-Air'."));
669 const QString& _grabber,
671 m_parent(_parent), m_grabber(_grabber)
675 QString
filename = QString(
"%1/%2.xmltv")
685 config->setHelpText(tr(
"Run XMLTV configure command."));
696 QString err_msg = QObject::tr(
697 "You MUST run 'mythfilldatabase --manual' the first time,\n"
698 "instead of just 'mythfilldatabase'.\nYour grabber does not provide "
699 "channel numbers, so you have to set them manually.");
703 LOG(VB_GENERAL, LOG_ERR, err_msg);
722 : m_useEit(new
UseEIT(_parent))
731 label->setValue(QObject::tr(
"Use only the transmitted guide data."));
733 QObject::tr(
"This will usually only work with ATSC or DVB channels, "
734 "and generally provides data only for the next few days."));
746 : m_useEit(new
UseEIT(_parent))
753 label->setValue(QObject::tr(
"Do not configure a grabber"));
769 setLabel(QObject::tr(
"Video Source Setup"));
791 const QString &thecardtype)
794 query.
prepare(
"SELECT count(cardtype)"
796 " WHERE capturecard.sourceid = :SOURCEID "
797 " AND capturecard.cardtype = :CARDTYPE ;");
799 query.
bindValue(
":CARDTYPE", thecardtype);
803 int count = query.
value(0).toInt();
815 result.
prepare(
"SELECT name, sourceid FROM videosource;");
819 while (result.
next())
822 source->setLabel(result.
value(0).toString());
823 source->loadByID(result.
value(1).toInt());
832 result.
prepare(
"SELECT name, sourceid FROM videosource;");
836 while (result.
next())
839 result.
value(1).toString());
854 uint minor_max = UINT_MAX,
855 const QString& card = QString(),
856 const QRegularExpression& driver = QRegularExpression()) :
859 setLabel(QObject::tr(
"Video device"));
862 QDir dev(
"/dev/v4l",
"video*", QDir::Name, QDir::System);
864 card, driver,
false);
869 card, driver,
false);
872 dev.setPath(
"/dev/dtv");
874 card, driver,
false);
878 dev.setNameFilters(QStringList(
"dtv*"));
880 card, driver,
false);
888 [[maybe_unused]]
bool absPath =
true)
override
895 const QString& card,
const QRegularExpression& driver,
896 bool allow_duplicates)
899 QFileInfoList entries = dir.entryInfoList();
900 for (
const auto & fi : std::as_const(entries))
903 QString filepath = fi.absoluteFilePath();
904 int err =
lstat(filepath.toLocal8Bit().constData(), &st);
908 LOG(VB_GENERAL, LOG_ERR,
909 QString(
"Could not stat file: %1").arg(filepath));
914 if (!S_ISCHR(st.st_mode))
919 if (minor_min > minor_num || minor_max < minor_num)
927 QByteArray tmp = filepath.toLatin1();
928 int videofd = open(tmp.constData(), O_RDWR);
935 auto match = driver.match(driver_name);
936 if ((!driver.pattern().isEmpty() || match.hasMatch()) &&
937 (card.isEmpty() || (card_name == card)))
969 setLabel(QObject::tr(
"VBI device"));
971 setHelpText(QObject::tr(
"Device to read VBI (captions) from."));
977 QDir dev(
"/dev/v4l",
"vbi*", QDir::Name, QDir::System);
983 if ((count == 0U) && !
getValue().isEmpty())
997 [[maybe_unused]]
bool absPath =
true)
override
1003 const QString &driver)
1005 QStringList devices;
1006 QFileInfoList entries = dir.entryInfoList();
1007 for (
const auto & fi : std::as_const(entries))
1009 QString device = fi.absoluteFilePath();
1010 QByteArray adevice = device.toLatin1();
1011 int vbifd = open(adevice.constData(), O_RDWR);
1018 (driver.isEmpty() || (dn == driver)) &&
1019 (card.isEmpty() || (cn == card)))
1021 devices.push_back(device);
1028 for (
const QString& device : std::as_const(devices))
1031 return (
uint) devices.size();
1044 setHelpText(QObject::tr(
"Specify the command to run, with any "
1045 "needed arguments."));
1062 setLabel(QObject::tr(
"File path"));
1078 setLabel(QObject::tr(
"Audio device"));
1080 QDir dev(
"/dev",
"dsp*", QDir::Name, QDir::System);
1082 dev.setPath(
"/dev/sound");
1085#if CONFIG_AUDIO_ALSA
1089 setHelpText(QObject::tr(
"Device to read audio from, "
1090 "if audio is separate from the video."));
1099 std::chrono::milliseconds min_val) :
1102 setLabel(QObject::tr(
"Signal timeout (ms)"));
1105 "Maximum time (in milliseconds) MythTV waits for "
1106 "a signal when scanning for channels."));
1109 template<
typename T>
1111 requires (std::is_floating_point_v<T>) :
1112 SignalTimeout(parent, value, duration_cast<std::chrono::milliseconds>(min_secs)) {};
1113 template<
typename T>
1115 requires (std::is_floating_point_v<T>) :
1117 duration_cast<std::chrono::milliseconds>(value),
1118 duration_cast<std::chrono::milliseconds>(min_secs)) {};
1126 std::chrono::milliseconds min_val) :
1129 setLabel(QObject::tr(
"Tuning timeout (ms)"));
1132 "Maximum time (in milliseconds) MythTV waits for "
1133 "a channel lock. For recordings, if this time is "
1134 "exceeded, the recording will be marked as failed."));
1137 template<
typename T>
1139 requires (std::is_floating_point_v<T>) :
1140 ChannelTimeout(parent, value, duration_cast<std::chrono::milliseconds>(min_secs)) {};
1141 template<
typename T>
1143 requires (std::is_floating_point_v<T>) :
1144 ChannelTimeout(parent, value, duration_cast<std::chrono::milliseconds>(min_secs)) {};
1153 setLabel(QObject::tr(
"Force audio sampling rate"));
1155 QObject::tr(
"If non-zero, override the audio sampling "
1156 "rate in the recording profile when this card is "
1157 "used. Use this if your capture card does not "
1158 "support all of the standard rates."));
1173 setLabel(QObject::tr(
"Do not adjust volume"));
1175 QObject::tr(
"Enable this option for budget BT878 based "
1176 "DVB-T cards such as the AverTV DVB-T which "
1177 "require the audio volume to be left alone."));
1192 setLabel(QObject::tr(
"DVB device"));
1194 QObject::tr(
"When you change this setting, the text below "
1195 "should change to the name and type of your card. "
1196 "If the card cannot be opened, an error message "
1197 "will be displayed."));
1213#ifdef __cpp_lib_ranges_contains
1214 !std::ranges::contains(sdevs,
current)
1222 std::stable_sort(sdevs.begin(), sdevs.end());
1227 QMap<QString,bool> in_use;
1229 for (
const QString& dev : std::as_const(sdevs))
1231 in_use[dev] = db.contains(dev);
1232 if (sel.isEmpty() && !in_use[dev])
1236 if (sel.isEmpty() && !sdevs.empty())
1239 QString usestr = QString(
" -- ");
1240 usestr += QObject::tr(
"Warning: already in use");
1242 for (
const QString& dev : std::as_const(sdevs))
1244 QString desc = dev + (in_use[dev] ? usestr :
"");
1245 desc = (
current == dev) ? dev : desc;
1269 setLabel(QObject::tr(
"Delivery system"));
1271 QObject::tr(
"If your card supports more than one delivery system "
1272 "then you can select here the one that you want to use."));
1281 setLabel(QObject::tr(
"Frontend ID"));
1283 QObject::tr(
"Identification string reported by the card. "
1284 "If the message \"Could not get card info...\" appears "
1285 "the card can be in use by another program."));
1296 setLabel(QObject::tr(
"Wait for SEQ start header"));
1299 QObject::tr(
"If enabled, drop packets from the start of a DVB "
1300 "recording until a sequence start header is seen."));
1316 setLabel(QObject::tr(
"Open DVB card on demand"));
1319 QObject::tr(
"If enabled, only open the DVB card when required, "
1320 "leaving it free for other programs at other times."));
1336 setLabel(QObject::tr(
"Use DVB card for active EIT scan"));
1339 QObject::tr(
"If enabled, activate active scanning for "
1340 "program data (EIT). When this option is enabled "
1341 "the DVB card is constantly in use."));
1356 setLabel(QObject::tr(
"DVB tuning delay (ms)"));
1359 QObject::tr(
"Some Linux DVB drivers, in particular for the "
1360 "Hauppauge Nova-T, require that we slow down "
1361 "the tuning process by specifying a delay "
1362 "(in milliseconds)."));
1375 for (
auto & i : list)
1377 QString guid = i.GetGUIDString();
1396 setLabel(QObject::tr(
"Cable box model"));
1397 addSelection(QObject::tr(
"Motorola Generic"),
"MOTO GENERIC");
1398 addSelection(QObject::tr(
"SA/Cisco Generic"),
"SA GENERIC");
1414 QString
help = QObject::tr(
1415 "Choose the model that most closely resembles your set top box. "
1416 "Depending on firmware revision SA4200HD may work better for a "
1436 name.replace(
"Scientific-Atlanta",
"SA");
1437 name.replace(
", Inc.",
"");
1438 name.replace(
"Explorer(R)",
"");
1439 name = name.simplified();
1440 setValue((name.isEmpty()) ?
"" : name);
1449 "firewire_connection"))
1451 setLabel(QObject::tr(
"Connection Type"));
1494#if CONFIG_FIREWIRE_LINUX
1502 model->SetGUID(dev->getValue());
1503 desc->SetGUID(dev->getValue());
1517HDHomeRunDeviceID::HDHomeRunDeviceID(
const CaptureCard &parent,
1518 HDHomeRunConfigurationGroup &_group) :
1526HDHomeRunDeviceID::~HDHomeRunDeviceID()
1528 delete GetStorage();
1531void HDHomeRunDeviceID::Load(
void)
1534 m_group.SetDeviceCheckBoxes(getValue());
1537void HDHomeRunDeviceID::Save(
void)
1539 setValue(m_group.GetDeviceCheckBoxes());
1546 explicit HDHomeRunEITScan(
const CaptureCard &parent) :
1550 setLabel(QObject::tr(
"Use HDHomeRun for active EIT scan"));
1553 QObject::tr(
"If enabled, activate active scanning for "
1554 "program data (EIT). When this option is enabled "
1555 "the HDHomeRun is constantly in use."));
1558 ~HDHomeRunEITScan()
override
1568 explicit UseHDHomeRunDevice(QString &deviceid, QString &model,
1571 setLabel(QObject::tr(
"Use HDHomeRun %1 (%2 %3)")
1572 .arg(deviceid, model, ipaddr));
1575 QObject::tr(
"If enabled, use tuners from this HDHomeRun "
1580HDHomeRunConfigurationGroup::HDHomeRunConfigurationGroup
1583 m_deviceId(new HDHomeRunDeviceID(a_parent, *this))
1590 QMap<QString, HDHomeRunDevice>::iterator dit;
1591 for (dit = m_deviceList.begin(); dit != m_deviceList.end(); ++dit)
1593 HDHomeRunDevice &dev = *dit;
1594 dev.m_checkbox =
new UseHDHomeRunDevice(
1595 dev.m_deviceId, dev.m_model, dev.m_cardIp);
1603 buttonRecOpt->setLabel(tr(
"Recording Options"));
1606 buttonRecOpt->addChild(
new HDHomeRunEITScan(
m_parent));
1610void HDHomeRunConfigurationGroup::FillDeviceList(
void)
1612 m_deviceList.clear();
1618 for (
const auto & dev : std::as_const(devs))
1620 QStringList devinfo = dev.split(
" ");
1621 const QString& devid = devinfo.at(0);
1622 const QString& devip = devinfo.at(1);
1623 const QString& model = devinfo.at(2);
1625 HDHomeRunDevice tmpdevice;
1626 tmpdevice.m_model = model;
1627 tmpdevice.m_cardIp = devip;
1628 tmpdevice.m_deviceId = devid;
1631 tmpdevice.m_checkbox =
nullptr;
1632 m_deviceList[tmpdevice.m_deviceId] = tmpdevice;
1637 QMap<QString, HDHomeRunDevice>::iterator debugit;
1638 for (debugit = m_deviceList.begin(); debugit != m_deviceList.end(); ++debugit)
1640 LOG(VB_GENERAL, LOG_DEBUG, QString(
"%1: %2 %3")
1641 .arg(debugit.key()).arg((*debugit).model)
1642 .arg((*debugit).cardip));
1647void HDHomeRunConfigurationGroup::SetDeviceCheckBoxes(
const QString& devices)
1649 QStringList devstrs = devices.split(
",");
1650 for (
const QString& devstr : std::as_const(devstrs))
1655 QByteArray ba = devstr.toUtf8();
1657 ba.data(),
nullptr);
1660 QString devid = QString(
"%1").arg(
1661 hdhomerun_device_get_device_id(device), 8, 16).toUpper();
1662 hdhomerun_device_destroy(device);
1665 QMap<QString, HDHomeRunDevice>::iterator dit;
1666 dit = m_deviceList.find(devid);
1667 if (dit != m_deviceList.end())
1668 (*dit).m_checkbox->setValue(
true);
1672QString HDHomeRunConfigurationGroup::GetDeviceCheckBoxes(
void)
1676 QStringList devstrs;
1677 QMap<QString, HDHomeRunDevice>::iterator dit;
1678 for (dit = m_deviceList.begin(); dit != m_deviceList.end(); ++dit)
1680 if ((*dit).m_checkbox->boolValue())
1681 devstrs << (*dit).m_deviceId;
1683 QString devices = devstrs.join(
",");
1695 setLabel(QObject::tr(
"IP Address"));
1696 setHelpText(QObject::tr(
"Device IP or ID of a VBox device. eg. '192.168.1.100' or 'vbox_3718'"));
1726 setHelpText(QObject::tr(
"Number and type of the tuner to use. eg '1-DVBT/T2'."));
1800 m_deviceId(deviceid),
1803 m_cardTuner(cardtuner),
1804 m_deviceList(devicelist),
1807 setLabel(QObject::tr(
"Available devices"));
1810 "Device IP or ID, tuner number and tuner type of available VBox devices."));
1821 std::vector<QString> devs;
1822 QMap<QString, bool> in_use;
1828 devs.push_back(it.key());
1829 in_use[it.key()] = (*it).m_inUse;
1832 QString man_addr = VBoxDeviceIDList::tr(
"Manually Enter IP Address");
1833 QString sel = man_addr;
1834 devs.push_back(sel);
1836 for (
const auto & dev : devs)
1837 sel = (
current == dev) ? dev : sel;
1839 QString usestr = QString(
" -- ");
1840 usestr += QObject::tr(
"Warning: already in use");
1842 for (
const auto & dev : devs)
1844 QString desc = dev + (in_use[dev] ? usestr :
"");
1852 else if (sel == man_addr && !
current.isEmpty())
1855 QStringList selection =
current.split(
"-");
1876 if (v == VBoxDeviceIDList::tr(
"Manually Enter IP Address"))
1881 else if (!v.isEmpty())
1883 if (
m_oldValue == VBoxDeviceIDList::tr(
"Manually Enter IP Address"))
1908 setValue(
"http://mafreebox.freebox.fr/freeboxtv/playlist.m3u");
1911 QObject::tr(
"URL of M3U file containing RTSP/RTP/UDP/HTTP channel URLs,"
1912 " example for HDHomeRun: http://<ipv4>/lineup.m3u and for Freebox:"
1913 " http://mafreebox.freebox.fr/freeboxtv/playlist.m3u."
1932 setLabel(QObject::tr(
"ASI device"));
1951 std::stable_sort(sdevs.begin(), sdevs.end());
1960 QMap<QString,bool> in_use;
1962 for (
const QString& dev : std::as_const(sdevs))
1964 in_use[dev] = db.contains(dev);
1965 if (sel.isEmpty() && !in_use[dev])
1970 if (sel.isEmpty() && !sdevs.empty())
1973 QString usestr = QString(
" -- ");
1974 usestr += QObject::tr(
"Warning: already in use");
1978 for (
const QString& dev : std::as_const(sdevs))
1980 QString desc = dev + (in_use[dev] ? usestr :
"");
1981 desc = (
current == dev) ? dev : desc;
1983 found |= (dev == sel);
1987 if (!found && !
current.isEmpty())
1989 QString desc =
current +
" -- " +
1990 QObject::tr(
"Warning: unable to open");
2028 if (device.isEmpty())
2045 LOG(VB_GENERAL, LOG_WARNING,
2046 "ASIConfigurationGroup::probeCard(), Warning: " +
error);
2062 device->setHelpText(tr(
"A local file used to simulate a recording."
2063 " Leave empty to use MythEvents to trigger an"
2064 " external program to import recording files."));
2086 QFileInfo fileInfo(device);
2089 if (device.startsWith(
"file:", Qt::CaseInsensitive))
2090 fileInfo.setFile(device.mid(5));
2092 if (fileInfo.exists())
2094 if (fileInfo.isReadable() && (fileInfo.isFile()))
2097 cs = tr(
"%1 MB").arg(fileInfo.size() / 1024 / 1024);
2101 ci = tr(
"File not readable");
2106 ci = tr(
"File %1 does not exist").arg(device);
2158 for (
const auto & dev : std::as_const(devs))
2160 QStringList devinfo = dev.split(
" ");
2161 const QString&
id = devinfo.at(0);
2162 const QString& ip = devinfo.at(1);
2163 const QString& tunerNo = devinfo.at(2);
2164 const QString& tunerType = devinfo.at(3);
2183 for (
const auto & dev : std::as_const(db))
2185 QMap<QString, VBoxDevice>::iterator dit;
2189 (*dit).m_inUse =
true;
2197CetonSetting::CetonSetting(QString label,
const QString& helptext)
2199 setLabel(std::move(label));
2200 setHelpText(helptext);
2202 this, &CetonSetting::UpdateDevices);
2205void CetonSetting::UpdateDevices(
const QString &v)
2211void CetonSetting::LoadValue(
const QString &value)
2216CetonDeviceID::CetonDeviceID(
const CaptureCard &parent) :
2224CetonDeviceID::~CetonDeviceID()
2226 delete GetStorage();
2229void CetonDeviceID::SetIP(
const QString &ip)
2231 static const QRegularExpression ipV4Regex
2232 {
"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){4}$" };
2233 auto match = ipV4Regex.match(ip +
".");
2234 if (match.hasMatch())
2237 setValue(QString(
"%1-RTP.%3").arg(m_ip, m_tuner));
2241void CetonDeviceID::SetTuner(
const QString &tuner)
2243 static const QRegularExpression oneDigit {
"^\\d$" };
2244 auto match = oneDigit.match(tuner);
2245 if (match.hasMatch())
2248 setValue(QString(
"%1-RTP.%2").arg(m_ip, m_tuner));
2252void CetonDeviceID::Load(
void)
2254 GetStorage()->Load();
2258void CetonDeviceID::UpdateValues(
void)
2260 static const QRegularExpression newstyle { R
"(^([0-9.]+)-(\d|RTP)\.(\d)$)" };
2261 auto match = newstyle.match(getValue());
2262 if (match.hasMatch())
2264 emit LoadedIP(match.captured(1));
2265 emit LoadedTuner(match.captured(3));
2271 auto *deviceid =
new CetonDeviceID(parent);
2273 desc->setLabel(tr(
"CetonConfigurationGroup",
"Description"));
2274 auto *ip =
new CetonSetting(tr(
"IP Address"),
2275 tr(
"IP Address of the Ceton device (192.168.200.1 by default)"));
2276 auto *tuner =
new CetonSetting(tr(
"Tuner"),
2277 tr(
"Number of the tuner on the Ceton device (first tuner is number 0)"));
2286 QObject::connect(ip, &CetonSetting::NewValue,
2287 deviceid, &CetonDeviceID::SetIP);
2288 QObject::connect(tuner, &CetonSetting::NewValue,
2289 deviceid, &CetonDeviceID::SetTuner);
2291 QObject::connect(deviceid, &CetonDeviceID::LoadedIP,
2292 ip, &CetonSetting::LoadValue);
2293 QObject::connect(deviceid, &CetonDeviceID::LoadedTuner,
2294 tuner, &CetonSetting::LoadValue);
2318 const QString &inputtype) :
2324 QRegularExpression drv {
"^(?!ivtv|hdpvr|(saa7164(.*))).*$" };
2348 QString cn = tr(
"Failed to open");
2352 QByteArray adevice = device.toLatin1();
2353 int videofd = open(adevice.constData(), O_RDWR);
2357 ci = cn = tr(
"Failed to probe");
2358 else if (!dn.isEmpty())
2359 ci = cn +
" [" + dn +
"]";
2374 QRegularExpression drv {
"^(ivtv|(saa7164(.*)))$" };
2397 QString cn = tr(
"Failed to open");
2401 QByteArray adevice = device.toLatin1();
2402 int videofd = open(adevice.constData(), O_RDWR);
2406 ci = cn = tr(
"Failed to probe");
2407 else if (!dn.isEmpty())
2408 ci = cn +
" [" + dn +
"]";
2424 device->setHelpText(tr(
"A local MPEG file used to simulate a recording."));
2447 QFileInfo fileInfo(device);
2448 if (fileInfo.exists())
2450 if (fileInfo.isReadable() && (fileInfo.isFile()))
2453 cs = tr(
"%1 MB").arg(fileInfo.size() / 1024 / 1024);
2457 ci = tr(
"File not readable");
2462 ci = tr(
"File does not exist");
2470ExternalConfigurationGroup::ExternalConfigurationGroup(
CaptureCard &a_parent,
2477 device->setLabel(tr(
"Command path"));
2478 device->setHelpText(tr(
"A 'black box' application controlled via stdin, status on "
2479 "stderr and TransportStream read from stdout.\n"
2480 "Use absolute path or path relative to the current directory."));
2490 this, &ExternalConfigurationGroup::probeApp);
2492 probeApp(device->getValue());
2495void ExternalConfigurationGroup::probeApp(
const QString & path)
2497 int idx1 = path.startsWith(
"file:", Qt::CaseInsensitive) ? 5 : 0;
2498 int idx2 = path.indexOf(
' ', idx1);
2501 QFileInfo fileInfo(path.mid(idx1, idx2 - idx1));
2503 if (fileInfo.exists())
2505 ci = tr(
"File '%1' is valid.").arg(fileInfo.absoluteFilePath());
2506 if (!fileInfo.isReadable() || !fileInfo.isFile())
2507 ci = tr(
"WARNING: File '%1' is not readable.")
2508 .arg(fileInfo.absoluteFilePath());
2509 if (!fileInfo.isExecutable())
2510 ci = tr(
"WARNING: File '%1' is not executable.")
2511 .arg(fileInfo.absoluteFilePath());
2515 ci = tr(
"WARNING: File '%1' does not exist.")
2516 .arg(fileInfo.absoluteFilePath());
2519 m_info->setValue(ci);
2520 m_info->setHelpText(ci);
2532 QRegularExpression(
"^hdpvr$"));
2555 QString cn = tr(
"Failed to open");
2559 int videofd = open(device.toLocal8Bit().constData(), O_RDWR);
2563 ci = cn = tr(
"Failed to probe");
2564 else if (!dn.isEmpty())
2565 ci = cn +
" [" + dn +
"]";
2581 setLabel(QObject::tr(
"V4L2 encoder devices (multirec capable)"));
2596 if (!device_name.isEmpty())
2603 QString card_name = tr(
"Failed to open");
2604 QString card_info = card_name;
2623 if (audioinput->fillSelections(device_name) > 1)
2625 audioinput->setName(
"AudioInput");
2638 vbidev->setName(
"VBIDevice");
2656 setLabel(QObject::tr(
"Capture Card Setup"));
2658 auto* cardtype =
new CardType(parent);
2673 new HDHomeRunConfigurationGroup(parent, *cardtype));
2683 new SatIPConfigurationGroup(parent, *cardtype));
2687 FirewireConfigurationGroup(parent, *cardtype);
2691 CetonSetting::CetonConfigurationGroup(parent, *cardtype);
2722 new ExternalConfigurationGroup(parent,
2748 "SELECT cardid, videodevice, cardtype, displayname "
2750 "WHERE hostname = :HOSTNAME AND parentid = 0 "
2764 while (query.
next())
2767 QString videodevice = query.
value(1).toString();
2768 QString cardtype = query.
value(2).toString();
2769 QString displayname = query.
value(3).toString();
2771 QString label = QString(
"%1 (%2)")
2775 card->loadByID(cardid);
2776 card->setLabel(label);
2813 if (dev != init_dev)
2815 if (!init_dev.isEmpty())
2834 for (
uint clone : clones)
2851 setLabel(QObject::tr(
"Card type"));
2852 setHelpText(QObject::tr(
"Change the cardtype to the appropriate type for "
2853 "the capture card you are configuring."));
2861 QObject::tr(
"DVB-T/S/C, ATSC or ISDB-T tuner card"),
"DVB");
2866 QObject::tr(
"V4L2 encoder"),
"V4L2ENC");
2868 QObject::tr(
"HD-PVR H.264 encoder"),
"HDPVR");
2873 QObject::tr(
"HDHomeRun networked tuner"),
"HDHOMERUN");
2878 QObject::tr(
"Sat>IP networked tuner"),
"SATIP");
2883 QObject::tr(
"V@Box TV Gateway networked tuner"),
"VBOX");
2888 QObject::tr(
"FireWire cable box"),
"FIREWIRE");
2893 QObject::tr(
"Ceton Cablecard tuner"),
"CETON");
2897 setting->
addSelection(QObject::tr(
"IPTV recorder"),
"FREEBOX");
2902 QObject::tr(
"Analog to MPEG-2 encoder card (PVR-150/250/350, etc)"),
"MPEG");
2904 QObject::tr(
"Analog to MJPEG encoder card (Matrox G200, DC10, etc)"),
"MJPEG");
2906 QObject::tr(
"Analog to MPEG-4 encoder (Plextor ConvertX USB, etc)"),
2909 QObject::tr(
"Analog capture card"),
"V4L");
2913 setting->
addSelection(QObject::tr(
"DVEO ASI recorder"),
"ASI");
2916 setting->
addSelection(QObject::tr(
"Import test recorder"),
"IMPORT");
2917 setting->
addSelection(QObject::tr(
"Demo test recorder"),
"DEMO");
2919 setting->
addSelection(QObject::tr(
"External (black box) recorder"),
2942 setLabel(QObject::tr(
"Input name"));
2958 addSelection(QObject::tr(
"(None)"),
"None");
2960 if (storage ==
nullptr)
2967 while (!inputs.isEmpty())
2969 addSelection(inputs.front());
2980 setLabel(QObject::tr(
"Delivery system"));
2982 "This shows the delivery system (modulation), for instance DVB-T2, "
2983 "that you have selected when you configured the capture card. "
2984 "This must be the same as the modulation used by the video source. "));
2996 setLabel(QObject::tr(
"Display name"));
2998 "This name is displayed on screen when Live TV begins "
2999 "and in various other places. Make sure the last two "
3000 "characters are unique for each input or use a "
3001 "slash ('/') to designate the unique portion."));
3037 setLabel(QObject::tr(
"Video source"));
3038 addSelection(QObject::tr(
"(None)"),
"0");
3049 addSelection(QObject::tr(
"(None)"),
"0");
3058 m_cardInput(parent),
3059 m_groupNum(group_num)
3061 setLabel(QObject::tr(
"Input group") +
3062 QString(
" %1").arg(m_groupNum + 1));
3064 "Leave as 'Generic' unless this input is shared with "
3065 "another device. Only one of the inputs in an input "
3066 "group will be allowed to record at any given time."));
3069 void Load(
void)
override;
3073 uint inputid = m_cardInput.getInputID();
3076 if (m_groupId && (m_groupId != new_groupid))
3094 LOG(VB_GENERAL, LOG_DEBUG, QString(
"InputGroup::Load() %1 %2")
3095 .arg(m_groupNum).arg(m_cardInput.getInputID()));
3098 uint inputid = m_cardInput.getInputID();
3099 QMap<uint, uint> grpcnt;
3100 std::vector<QString> names;
3101 std::vector<uint> grpid;
3102 std::vector<uint> selected_groupids;
3104 names.push_back(QObject::tr(
"Generic"));
3110 "SELECT cardinputid, inputgroupid, inputgroupname "
3112 "WHERE inputgroupname LIKE 'user:%' "
3113 "ORDER BY inputgroupid, cardinputid, inputgroupname");
3121 while (query.
next())
3124 if ((inputid != 0U) && (query.
value(0).toUInt() == inputid))
3125 selected_groupids.push_back(groupid);
3129 if (grpcnt[groupid] == 1)
3131 names.push_back(query.
value(2).toString().mid(5, -1));
3132 grpid.push_back(groupid);
3139 if (m_groupNum < selected_groupids.size())
3140 m_groupId = selected_groupids[m_groupNum];
3143 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Group num: %1 id: %2")
3144 .arg(m_groupNum).arg(m_groupId));
3147 for (
uint i = 0; i < selected_groupids.size(); i++)
3148 msg += QString(
"%1 ").arg(selected_groupids[i]);
3149 LOG(VB_GENERAL, LOG_DEBUG, msg);
3156 for (
size_t i = 0; i < names.size(); i++)
3158 bool sel = (m_groupId == grpid[i]);
3159 index = sel ? i : index;
3162 LOG(VB_GENERAL, LOG_DEBUG, QString(
"grpid %1, name '%2', i %3, s %4")
3163 .arg(grpid[i]).arg(names[i]) .arg(index).arg(sel ?
"T" :
"F"));
3166 addSelection(names[i], QString::number(grpid[i]), sel);
3170 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Group index: %1").arg(index));
3185 setLabel(QObject::tr(
"Use quick tuning"));
3186 addSelection(QObject::tr(
"Never"),
"0",
true);
3187 addSelection(QObject::tr(
"Live TV only"),
"1",
false);
3188 addSelection(QObject::tr(
"Always"),
"2",
false);
3190 "If enabled, MythTV will tune using only the "
3191 "MPEG program number. The program numbers "
3192 "change more often than DVB or ATSC tuning "
3193 "parameters, so this is slightly less reliable. "
3194 "This will also inhibit EIT gathering during "
3195 "Live TV and recording."));
3205 setLabel(QObject::tr(
"External channel change command"));
3207 setHelpText(QObject::tr(
"If specified, this command will be run to "
3208 "change the channel for inputs which have an external "
3209 "tuner device such as a cable box. The first argument "
3210 "will be the channel number."));
3225 setLabel(QObject::tr(
"Preset tuner to channel"));
3227 setHelpText(QObject::tr(
"Leave this blank unless you have an external "
3228 "tuner that is connected to the tuner input of your card. "
3229 "If so, you will need to specify the preset channel for "
3230 "the signal (normally 3 or 4)."));
3242 if (sourceid.isEmpty() || !sourceid.toUInt())
3247 if (storage ==
nullptr)
3254 if (channels.empty())
3256 addSelection(tr(
"Please add channels to this source"),
3257 startChan.isEmpty() ?
"0" : startChan);
3265 bool has_visible =
false;
3266 for (
size_t i = 0; i < channels.size() && !has_visible; i++)
3269 for (
auto & channel : channels)
3271 const QString channum = channel.m_chanNum;
3272 bool sel = channum == startChan;
3273 if (!has_visible || channel.m_visible || sel)
3275 addSelection(channum, channum, sel);
3287 setLabel(QObject::tr(
"Input priority"));
3289 setHelpText(QObject::tr(
"If the input priority is not equal for "
3290 "all inputs, the scheduler may choose to record a show "
3291 "at a later time so that it can record on an input with "
3292 "a higher value."));
3308 setLabel(QObject::tr(
"Schedule order"));
3310 setHelpText(QObject::tr(
"If priorities and other factors are equal "
3311 "the scheduler will choose the available "
3312 "input with the lowest, non-zero value. "
3313 "Setting this value to zero will make the "
3314 "input unavailable to the scheduler."));
3330 setLabel(QObject::tr(
"Live TV order"));
3332 setHelpText(QObject::tr(
"When entering Live TV, the available, local "
3333 "input with the lowest, non-zero value will "
3334 "be used. If no local inputs are available, "
3335 "the available, remote input with the lowest, "
3336 "non-zero value will be used. "
3337 "Setting this value to zero will make the "
3338 "input unavailable to live TV."));
3354 setLabel(QObject::tr(
"Use DishNet long-term EIT data"));
3358 "If you point your satellite dish toward DishNet's birds, "
3359 "you may wish to enable this feature. For best results, "
3360 "enable general EIT collection as well."));
3391 if (
"DVB" == cardtype)
3413 if (
"DVB" == cardtype)
3418 tr(
"Use channel scanner to find channels for this input."));
3421 tr(
"This uses the listings data source to "
3422 "provide the channels for this input.") +
" " +
3423 tr(
"This can take a long time to run."));
3432 interact->setLabel(QObject::tr(
"Interactions between inputs"));
3442 interact->addChild(
new LiveTVOrder(*
this, _cardid));
3446 ingrpbtn->setHelpText(
3447 QObject::tr(
"Input groups are only needed when two or more cards "
3448 "share the same resource such as a FireWire card and "
3449 "an analog card input controlling the same set top box."));
3450 interact->addChild(ingrpbtn);
3456 setObjectName(
"CardInput");
3482 bool enable = (sourceid.toInt() > 0);
3499 auto *settingdialog =
3502 if (settingdialog->Create())
3510 delete settingdialog;
3518 ShowOkPopup(tr(
"Sorry, this Input Group name cannot be blank."));
3522 QString new_name = QString(
"user:") + name;
3525 query.
prepare(
"SELECT inputgroupname "
3527 "WHERE inputgroupname = :GROUPNAME");
3528 query.
bindValue(
":GROUPNAME", new_name);
3538 ShowOkPopup(tr(
"Sorry, this Input Group name is already in use."));
3573 LOG(VB_GENERAL, LOG_ERR,
3574 QString(
"Sorry, %1 cards do not yet support scanning.")
3586 [srcid,
this, num_channels_before]()
3590 if (num_channels_before)
3604 LOG(VB_GENERAL, LOG_ERR,
"You must compile the backend "
3605 "to be able to scan for channels");
3625 cardtype !=
"HDHOMERUN" &&
3626 !num_channels_before)
3628 LOG(VB_GENERAL, LOG_ERR,
"Skipping channel fetch, you need to "
3629 "scan for channels first.");
3638 if (num_channels_before)
3647 QString cardinputidTag(
":WHERECARDID");
3649 QString query(
"cardid = " + cardinputidTag);
3658 QString cardinputidTag(
":SETCARDID");
3661 QString query(
"cardid = " + cardinputidTag +
", " +
3680 query.
prepare(
"SELECT cardid FROM capturecard "
3681 "WHERE cardid = :CARDID AND inputname = :INPUTNAME");
3683 query.
bindValue(
":INPUTNAME", _inputname);
3736 tr(
"Are you sure you want to delete "
3745 tr(
"Are you sure you want to delete "
3746 "ALL capture cards?"),
3754 card->setLabel(tr(
"New capture card"));
3780 "WHERE hostname = :HOSTNAME");
3786 tr(
"Error getting list of cards for this host. "
3787 "Unable to delete capturecards for %1")
3794 while (cards.
next())
3810 AddSelection(QObject::tr(
"(Delete all capture cards on %1)")
3813 AddSelection(QObject::tr(
"(Delete all capture cards)"),
3827 AddSelection(QObject::tr(
"(Delete all video sources)"),
3850 tr(
"Are you sure you want to delete "
3851 "ALL video sources?"),
3869 source->setLabel(tr(
"New video source"));
3891 "SELECT cardid, videodevice, cardtype, displayname "
3893 "WHERE hostname = :HOSTNAME "
3894 " AND parentid = 0 "
3904 while (query.
next())
3907 QString videodevice = query.
value(1).toString();
3908 QString cardtype = query.
value(2).toString();
3909 QString displayname = query.
value(3).toString();
3911 auto *cardinput =
new CardInput(cardtype, videodevice, cardid);
3912 cardinput->loadByID(cardid);
3913 QString inputlabel = QString(
"%1 (%2) -> %3")
3915 displayname, cardinput->getSourceName());
3917 cardinput->setLabel(inputlabel);
3925static QString remove_chaff(
const QString &name)
3928 QString short_name = name;
3929 if (short_name.startsWith(
"LG Electronics"))
3930 short_name = short_name.right(short_name.length() - 15);
3931 if (short_name.startsWith(
"Oren"))
3932 short_name = short_name.right(short_name.length() - 5);
3933 if (short_name.startsWith(
"Nextwave"))
3934 short_name = short_name.right(short_name.length() - 9);
3935 if (short_name.startsWith(
"frontend", Qt::CaseInsensitive))
3936 short_name = short_name.left(short_name.length() - 9);
3937 if (short_name.endsWith(
"VSB/QAM"))
3938 short_name = short_name.left(short_name.length() - 8);
3939 if (short_name.endsWith(
"VSB"))
3940 short_name = short_name.left(short_name.length() - 4);
3941 if (short_name.endsWith(
"DVB-T"))
3942 short_name = short_name.left(short_name.length() - 6);
3948 short_name = short_name.simplified();
3949 if (short_name.startsWith(
"or51211", Qt::CaseInsensitive))
3950 short_name =
"pcHDTV HD-2000";
3951 else if (short_name.startsWith(
"or51132", Qt::CaseInsensitive))
3952 short_name =
"pcHDTV HD-3000";
3953 else if (short_name.startsWith(
"bcm3510", Qt::CaseInsensitive))
3954 short_name =
"Air2PC v1";
3955 else if (short_name.startsWith(
"nxt2002", Qt::CaseInsensitive) ||
3956 short_name.startsWith(
"nxt200x", Qt::CaseInsensitive))
3957 short_name =
"Air2PC v2";
3958 else if (short_name.startsWith(
"lgdt3302", Qt::CaseInsensitive))
3959 short_name =
"DViCO HDTV3";
3960 else if (short_name.startsWith(
"lgdt3303", Qt::CaseInsensitive))
3961 short_name =
"DViCO v2 or Air2PC v3 or pcHDTV HD-5500";
3986 if (videodevice.isEmpty())
4004 QString err_open = tr(
"Could not open card %1").arg(videodevice);
4005 QString err_other = tr(
"Could not get card info for card %1").arg(videodevice);
4051 if (frontend_name.toLower().indexOf(
"usb") >= 0)
4058 if ((frontend_name ==
"DiBcom 3000P/M-C DVB-T") ||
4060 "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"))
4066 QString short_name = remove_chaff(frontend_name);
4067 m_buttonAnalog->setVisible(
4068 short_name.startsWith(
"zarlink zl10353",
4069 Qt::CaseInsensitive) ||
4070 short_name.startsWith(
"wintv hvr 900 m/r: 65008/a1c0",
4071 Qt::CaseInsensitive) ||
4072 short_name.startsWith(
"philips tda10046h",
4073 Qt::CaseInsensitive));
4079 QString short_name = remove_chaff(frontend_name);
4087 if (frontend_name ==
"Nextwave NXT200X VSB/QAM frontend")
4094 if (frontend_name.toLower().indexOf(
"usb") < 0)
4096 m_buttonAnalog->setVisible(
4097 short_name.startsWith(
"pchdtv", Qt::CaseInsensitive) ||
4098 short_name.startsWith(
"dvico", Qt::CaseInsensitive) ||
4099 short_name.startsWith(
"nextwave", Qt::CaseInsensitive));
4112 for (
const auto & item : std::as_const(delsyslist))
4114 LOG(VB_GENERAL, LOG_DEBUG, QString(
"DVBCardType: add deliverysystem:%1")
4122 if (!delsys.isEmpty())
4134 QString dev, QString
type) :
4136 m_lastDevice(std::move(dev)), m_lastCardType(std::move(
type))
4138 setLabel(QObject::tr(
"Audio input"));
4139 setHelpText(QObject::tr(
"If there is more than one audio input, "
4140 "select which one to use."));
4153 if (device.isEmpty())
4157 QStringList inputs =
4160 for (
uint i = 0; i < (
uint)inputs.size(); i++)
4165 return inputs.size();
4248 explicit DiSEqCPosition(
const CaptureCard &parent,
int value,
int min_val) :
4252 setLabel(QObject::tr(
"DiSEqC position"));
4253 setHelpText(QObject::tr(
"Position of the LNB on the DiSEqC switch. "
4254 "Leave at 1 if there is no DiSEqC switch "
4255 "and the LNB is directly connected to the SatIP server. "
4256 "This value is used as signal source (attribute src) in "
4257 "the SatIP tune command."));
4261 ~DiSEqCPosition()
override
4267SatIPConfigurationGroup::SatIPConfigurationGroup
4270 m_deviceId(new SatIPDeviceID(a_parent))
4276 m_friendlyName =
new SatIPDeviceAttribute(tr(
"Friendly name"), tr(
"Friendly name of the Sat>IP server"));
4277 m_tunerType =
new SatIPDeviceAttribute(tr(
"Tuner type"), tr(
"Type of the selected tuner"));
4278 m_tunerIndex =
new SatIPDeviceAttribute(tr(
"Tuner index"), tr(
"Index of the tuner on the Sat>IP server"));
4280 m_deviceIdList =
new SatIPDeviceIDList(
4281 m_deviceId, m_friendlyName, m_tunerType, m_tunerIndex, &m_deviceList,
m_parent);
4293 connect(m_deviceIdList, &SatIPDeviceIDList::NewTuner,
4294 m_deviceId, &SatIPDeviceID::SetTuner);
4297void SatIPConfigurationGroup::FillDeviceList(
void)
4299 m_deviceList.clear();
4305 for (
const auto & dev : std::as_const(devs))
4307 QStringList devparts = dev.split(
" ");
4308 const QString&
id = devparts.value(0);
4309 const QString& name = devparts.value(1);
4310 const QString& ip = devparts.value(2);
4311 const QString& tunerno = devparts.value(3);
4312 const QString& tunertype = devparts.value(4);
4315 device.m_deviceId = id;
4316 device.m_cardIP = ip;
4317 device.m_inUse =
false;
4318 device.m_friendlyName = name;
4319 device.m_tunerNo = tunerno;
4320 device.m_tunerType = tunertype;
4321 device.m_mythDeviceId = QString(
"%1:%2:%3").arg(
id, tunertype, tunerno);
4323 QString friendlyIdentifier = QString(
"%1, %2, Tuner #%3").arg(name, tunertype, tunerno);
4325 m_deviceList[device.m_mythDeviceId] = device;
4327 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"SatIP: Add %1 '%2' '%3'")
4328 .arg(device.m_mythDeviceId, device.m_friendlyName, friendlyIdentifier));
4334 for (
const auto& dev : std::as_const(db))
4336 auto dit = m_deviceList.find(dev);
4337 if (dit != m_deviceList.end())
4339 (*dit).m_inUse =
true;
4344SatIPDeviceIDList::SatIPDeviceIDList(
4345 SatIPDeviceID *deviceId,
4346 SatIPDeviceAttribute *friendlyName,
4347 SatIPDeviceAttribute *tunerType,
4348 SatIPDeviceAttribute *tunerIndex,
4349 SatIPDeviceList *deviceList,
4351 m_deviceId(deviceId),
4352 m_friendlyName(friendlyName),
4353 m_tunerType(tunerType),
4354 m_tunerIndex(tunerIndex),
4355 m_deviceList(deviceList),
4359 setHelpText(tr(
"Device IP or ID, tuner number and tuner type of available Sat>IP device"));
4362 this, &SatIPDeviceIDList::UpdateDevices);
4365void SatIPDeviceIDList::Load(
void)
4369 int cardid = m_parent.getCardID();
4372 fillSelections(device);
4375void SatIPDeviceIDList::UpdateDevices(
const QString &v)
4377 SatIPDevice dev = (*m_deviceList)[v];
4378 m_deviceId->setValue(dev.m_mythDeviceId);
4379 m_friendlyName->setValue(dev.m_friendlyName);
4380 m_tunerType->setValue(dev.m_tunerType);
4381 m_tunerIndex->setValue(dev.m_tunerNo);
4384void SatIPDeviceIDList::fillSelections(
const QString &cur)
4388 std::vector<QString> names;
4389 std::vector<QString> devs;
4390 QMap<QString, bool> in_use;
4395 SatIPDeviceList::iterator it = m_deviceList->begin();
4396 for(; it != m_deviceList->end(); ++it)
4398 QString friendlyIdentifier = QString(
"%1, %2, Tuner #%3")
4399 .arg((*it).m_friendlyName, (*it).m_tunerType, (*it).m_tunerNo);
4400 names.push_back(friendlyIdentifier);
4402 devs.push_back(it.key());
4403 in_use[it.key()] = (*it).m_inUse;
4406 for (
const auto& it2s : devs)
4408 sel = (
current == it2s) ? it2s : sel;
4411 QString usestr = QString(
" -- ");
4412 usestr += tr(
"Warning: already in use");
4414 for (
uint i = 0; i < devs.size(); ++i)
4416 const QString& dev = devs[i];
4417 const QString& name = names[i];
4418 bool dev_in_use = (dev == sel) ?
false : in_use[devs[i]];
4419 QString desc = name + (dev_in_use ? usestr :
"");
4420 addSelection(desc, dev, dev == sel);
4424SatIPDeviceID::SatIPDeviceID(
const CaptureCard &parent) :
4434SatIPDeviceID::~SatIPDeviceID()
4436 delete GetStorage();
4439void SatIPDeviceID::Load(
void)
4444void SatIPDeviceID::SetTuner(
const QString &tuner)
4449SatIPDeviceAttribute::SatIPDeviceAttribute(
const QString& label,
const QString& helptext)
4452 setHelpText(helptext);
std::vector< ChannelInfo > ChannelInfoList
TransTextEditSetting * m_cardInfo
void probeCard(const QString &device)
ASIConfigurationGroup(CaptureCard &parent, CardType &cardType)
ASIDevice(const CaptureCard &parent)
void fillSelections(const QString ¤t)
Adds all available cards to list If current is >= 0 it will be considered available even if no device...
AudioDevice(const CaptureCard &parent)
AudioRateLimit(const CaptureCard &parent)
BouquetID(const VideoSource &parent, signed int value, signed int min_val)
QString GetSetClause(MSqlBindings &bindings) const override
const CaptureCard & m_parent
QString GetWhereClause(MSqlBindings &bindings) const override
int getCardID(void) const
void ShowDeleteAllCaptureCardsDialog(void) const
void DeleteAllCaptureCardsOnHost(bool doDelete)
void(CaptureCardEditor::*)(void) const CCESlotConst
void(CaptureCardEditor::*)(void) CCESlot
void DeleteAllCaptureCards(bool doDelete)
void ShowDeleteAllCaptureCardsDialogOnHost(void) const
void AddSelection(const QString &label, CCESlot slot)
CaptureCardGroup(CaptureCard &parent)
~CaptureCardSpinBoxSetting() override
void setValueMs(std::chrono::duration< T > newSecs)
CaptureCardSpinBoxSetting(const CaptureCard &parent, std::chrono::milliseconds min_val, std::chrono::milliseconds max_val, std::chrono::milliseconds step, const QString &setting)
void setValueMs(std::chrono::milliseconds newValue)
CaptureCardTextEditSetting(const CaptureCard &parent, const QString &setting)
~CaptureCardTextEditSetting() override
Hostname(const CaptureCard &parent)
void deleteEntry(void) override
QString GetRawCardType(void) const
bool canDelete(void) override
int getCardID(void) const
CaptureCard(bool use_card_group=true)
static void fillSelections(GroupSetting *setting)
static void fillSelections(MythUIComboBoxSetting *setting)
CardType(const CaptureCard &parent)
static int GetASIDeviceNumber(const QString &device, QString *error=nullptr)
static bool IsTunerSharingCapable(const QString &rawtype)
static INPUT_TYPES toInputType(const QString &name)
static void GetDeviceInputNames(const QString &device, const QString &inputtype, QStringList &inputs)
static bool IsUnscanable(const QString &rawtype)
static uint CreateInputGroup(const QString &name)
static QString GetRawInputType(uint inputid)
static QString GetAudioDevice(uint inputid)
static QString ProbeDVBFrontendName(const QString &device)
Returns the input type from the video device.
static QString ProbeDVBType(const QString &device)
static bool InputSetMaxRecordings(uint parentid, uint max_recordings)
static QStringList ProbeDeliverySystems(const QString &device)
static uint CreateDeviceInputGroup(uint inputid, const QString &type, const QString &host, const QString &device)
static QString GetStartChannel(uint inputid)
static QString GetDeviceLabel(const QString &inputtype, const QString &videodevice)
static QString GetVBoxdesc(const QString &id, const QString &ip, const QString &tunerNo, const QString &tunerType)
Get a nicely formatted string describing the device.
static QStringList GetVideoDevices(const QString &rawtype, QString hostname=QString())
Returns the videodevices of the matching inputs, duplicates removed.
static bool HasTuner(const QString &rawtype, const QString &device)
static QString GetDeliverySystemFromDB(uint inputid)
static bool UnlinkInputGroup(uint inputid, uint inputgroupid)
static bool LinkInputGroup(uint inputid, uint inputgroupid)
static QString GetVideoDevice(uint inputid)
static bool IsInNeedOfExternalInputConf(uint inputid)
static void ClearVideoDeviceCache()
static uint CloneCard(uint src_inputid, uint dst_inputid)
static bool IsV4L(const QString &rawtype)
static std::vector< uint > GetChildInputIDs(uint inputid)
static QString GetDeviceName(dvb_dev_type_t type, const QString &device)
static bool IsEncoder(const QString &rawtype)
static bool DeleteInput(uint inputid)
static QString ProbeDefaultDeliverySystem(const QString &device)
static QStringList ProbeVideoDevices(const QString &rawtype)
static bool IsCableCardPresent(uint inputid, const QString &inputType)
static bool GetV4LInfo(int videofd, QString &input, QString &driver, uint32_t &version, uint32_t &capabilities)
static bool DeleteAllInputs(void)
static QStringList ProbeAudioInputs(const QString &device, const QString &inputtype=QString())
static uint GetDeviceInputGroup(uint inputid)
ChannelTimeout(const CaptureCard &parent, std::chrono::milliseconds value, std::chrono::milliseconds min_val)
ChannelTimeout(const CaptureCard &parent, std::chrono::milliseconds value, std::chrono::duration< T > min_secs)
ChannelTimeout(const CaptureCard &parent, std::chrono::duration< T > value, std::chrono::duration< T > min_secs)
static void SortChannels(ChannelInfoList &list, const QString &order, bool eliminate_duplicates=false)
static ChannelInfoList GetAllChannels(uint sourceid)
Returns channels that are not connected to an input and channels that are not marked as visible.
CommandPath(const CaptureCard &parent)
QString GetColumnName(void) const
void fillSelections(const QString ¤t)
Adds all available cards to list If current is >= 0 it will be considered available even if no device...
DVBCardNum(const CaptureCard &parent)
DVBCardType(const CaptureCard &parent)
void reloadDiseqcTree(const QString &device)
DiSEqCDevTree * m_diseqcTree
DVBConfigurationGroup(CaptureCard &a_parent, CardType &cardType)
~DVBConfigurationGroup() override
SignalTimeout * m_signalTimeout
ChannelTimeout * m_channelTimeout
void probeCard(const QString &videodevice)
DVBTuningDelay * m_tuningDelay
DVBEITScan(const CaptureCard &parent)
DVBNetID(const VideoSource &parent, signed int value, signed int min_val)
~DVBNoSeqStart() override
DVBNoSeqStart(const CaptureCard &parent)
DVBOnDemand(const CaptureCard &parent)
DVBTuningDelay(const CaptureCard &parent)
DemoConfigurationGroup(CaptureCard &parent, CardType &cardtype)
void probeCard(const QString &device)
DVB-S device settings class.
bool Store(uint card_input_id) const
Stores configuration chain to DB for specified card input id.
bool Load(uint card_input_id)
Loads configuration chain from DB for specified card input id.
bool Load(const QString &device)
Loads the device tree from the database.
bool Store(uint cardid, const QString &device="")
Stores the device tree to the database.
static bool Exists(int cardid)
Check if a Diseqc device tree exists.
static void InvalidateTrees(void)
Invalidate cached trees.
DishNetEIT(const CardInput &parent)
EITOnly_config(const VideoSource &_parent, StandardSetting *_setting)
~ExternalChannelCommand() override
ExternalChannelCommand(const CardInput &parent)
FileDevice(const CaptureCard &parent)
FirewireConnection(const CaptureCard &parent)
~FirewireConnection() override
const FirewireGUID * m_guid
void SetGUID(const QString &_guid)
static std::vector< AVCInfo > GetSTBList(void)
static QString GetModelName(uint vendor_id, uint model_id)
AVCInfo GetAVCInfo(const QString &guid) const
FirewireGUID(const CaptureCard &parent)
QMap< QString, AVCInfo > m_guidToAvcInfo
const FirewireGUID * m_guid
FirewireModel(const CaptureCard &parent, const FirewireGUID *_guid)
void SetGUID(const QString &_guid)
FirewireSpeed(const CaptureCard &parent)
~FirewireSpeed() override
FreqTableSelector(const VideoSource &parent)
~FreqTableSelector() override
void probeCard(const QString &device)
GroupSetting * m_cardInfo
TunerCardAudioInput * m_audioInput
HDPVRConfigurationGroup(CaptureCard &parent, CardType &cardtype)
static QString TestMimeType(const QString &sFileName)
IPTVHost(const CaptureCard &parent)
void setValue(int value) override
ImportConfigurationGroup(CaptureCard &parent, CardType &cardtype)
void probeCard(const QString &device)
~InstanceCount() override
InstanceCount(const CardInput &parent)
LCNOffset(const VideoSource &parent, signed int value, signed int min_val)
LiveTVOrder(const CardInput &parent, int _value)
void probeCard(const QString &device)
MPEGConfigurationGroup(CaptureCard &parent, CardType &cardtype)
GroupSetting * m_cardInfo
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool isActive(void) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
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.
QString GetHostName(void)
QString GetSetting(const QString &key, const QString &defaultval="")
static void DBError(const QString &where, const MSqlQuery &query)
MythScreenStack * GetMainStack()
MythScreenStack * GetStack(const QString &Stackname)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Screen in which all other widgets are contained and rendered.
virtual bool Create(void)
uint Wait(std::chrono::seconds timeout=0s)
void Run(std::chrono::seconds timeout=0s)
Runs a command inside the /bin/sh shell. Returns immediately.
Dialog prompting the user to enter a text string.
void setValue(const QString &newValue) override
virtual void addSelection(const QString &label, QString value=QString(), bool select=false)
QString getValueLabel(void) const
virtual void fillSelectionsFromDir(const QDir &dir, bool absPath=true)
void setValue(int value) override
int getValueIndex(const QString &value) const
NoGrabber_config(const VideoSource &_parent)
PresetTuner(const CardInput &parent)
QuickTune(const CardInput &parent)
RegionID(const VideoSource &parent, signed int value, signed int min_val)
~ScanFrequencyStart() override
ScanFrequencyStart(const VideoSource &parent)
SchedGroupFalse(const CaptureCard &parent)
~SchedGroupFalse() override
SchedGroup(const CardInput &parent)
~ScheduleOrder() override
ScheduleOrder(const CardInput &parent, int _value)
SignalTimeout(const CaptureCard &parent, std::chrono::milliseconds value, std::chrono::milliseconds min_val)
SignalTimeout(const CaptureCard &parent, std::chrono::milliseconds value, std::chrono::duration< T > min_secs)
SignalTimeout(const CaptureCard &parent, std::chrono::duration< T > value, std::chrono::duration< T > min_secs)
SkipBtAudio(const CaptureCard &parent)
SourceID(const CardInput &parent)
static bool GetListingsLoginData(uint sourceid, QString &grabber, QString &userid, QString &passwd, QString &lineupid)
static bool DeleteSource(uint sourceid)
static bool DeleteAllSources(void)
static uint GetChannelCount(uint sourceid)
static bool UpdateChannelsFromListings(uint sourceid, const QString &inputtype=QString(), bool wait=false)
virtual void addChild(StandardSetting *child)
StandardSetting * m_parent
virtual void setReadOnly(bool readonly)
void addTargetedChild(const QString &value, StandardSetting *setting)
virtual void clearSettings()
void settingsChanged(StandardSetting *selectedSetting=nullptr)
virtual void setHelpText(const QString &str)
StandardSetting * getParent() const
void setVisible(bool visible)
virtual QList< StandardSetting * > * getSubSettings()
virtual void setValue(const QString &newValue)
Storage * GetStorage(void) const
void valueChanged(const QString &newValue)
virtual QString getValue(void) const
virtual void setEnabled(bool enabled)
virtual void setLabel(QString str)
void SetSourceID(const QString &sourceid)
virtual QString GetDBValue(void) const =0
virtual void Load(void)=0
QString m_loadedFreqTable
void SetSourceID(uint sourceid)
TransFreqTableSelector(uint sourceid)
UseEIT(const VideoSource &parent)
GroupSetting * m_cardInfo
void probeCard(const QString &device)
V4L2encGroup(CaptureCard &parent, CardType &cardType)
QString DriverName(void) const
bool HasSlicedVBI(void) const
QString CardName(void) const
V4LConfigurationGroup(CaptureCard &parent, CardType &cardtype, const QString &inputtype)
void probeCard(const QString &device)
GroupSetting * m_cardInfo
VBIDevice(const CaptureCard &parent)
uint fillSelectionsFromDir(const QDir &dir, const QString &card, const QString &driver)
uint setFilter(const QString &card, const QString &driver)
void fillSelectionsFromDir(const QDir &dir, bool absPath=true) override
VBoxDeviceList m_deviceList
VBoxDeviceID * m_deviceId
VBoxDeviceIDList * m_deviceIdList
void FillDeviceList(void)
VBoxTunerIndex * m_cardTuner
VBoxConfigurationGroup(CaptureCard &parent, CardType &cardtype)
void fillSelections(const QString ¤t)
Adds all available device-tuner combinations to list.
VBoxDeviceID * m_deviceId
const CaptureCard & m_parent
VBoxDeviceList * m_deviceList
VBoxTunerIndex * m_cardTuner
void UpdateDevices(const QString &v)
VBoxDeviceIDList(VBoxDeviceID *deviceid, StandardSetting *desc, VBoxIP *cardip, VBoxTunerIndex *cardtuner, VBoxDeviceList *devicelist, const CaptureCard &parent)
void SetTuner(const QString &tuner)
void SetOverrideDeviceID(const QString &deviceid)
VBoxDeviceID(const CaptureCard &parent)
void SetIP(const QString &ip)
QString m_overrideDeviceId
void NewIP(const QString &)
void SetOldValue(const QString &s)
void setEnabled(bool e) override
void UpdateDevices(const QString &v)
void UpdateDevices(const QString &v)
void setEnabled(bool e) override
void NewTuner(const QString &)
void SetOldValue(const QString &s)
void fillSelectionsFromDir(const QDir &dir, bool absPath=true) override
VideoDevice(const CaptureCard &parent, uint minor_min=0, uint minor_max=UINT_MAX, const QString &card=QString(), const QRegularExpression &driver=QRegularExpression())
QString Driver(void) const
uint fillSelectionsFromDir(const QDir &dir, uint minor_min, uint minor_max, const QString &card, const QRegularExpression &driver, bool allow_duplicates)
QMap< uint, uint > m_minorList
QString GetWhereClause(MSqlBindings &bindings) const override
const VideoSource & m_parent
QString GetSetClause(MSqlBindings &bindings) const override
void DeleteAllSources(bool doDelete)
static bool cardTypesInclude(int SourceID, const QString &thecardtype)
void(VideoSourceEditor::*)(void) VSESlot
void ShowDeleteAllSourcesDialog(void) const
void(VideoSourceEditor::*)(void) const VSESlotConst
void AddSelection(const QString &label, VSESlot slot)
VideoSourceSelector(uint _initial_sourceid, QString _card_types, bool _must_have_mplexid)
VideoSourceShow(uint _initial_sourceid)
static void fillSelections(GroupSetting *setting)
int getSourceID(void) const
QString getSourceName(void) const
bool canDelete(void) override
void deleteEntry(void) override
void LoadXMLTVGrabbers(QStringList name_list, QStringList prog_list)
static QStringList m_nameList
static QStringList m_progList
XMLTVGrabber(const VideoSource &parent)
const VideoSource & m_parent
QStringList m_grabberArgs
const VideoSource & m_parent
XMLTV_generic_config(const VideoSource &_parent, const QString &_grabber, StandardSetting *_setting)
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
@ GENERIC_EXIT_OK
Exited with no error.
const CHANLISTS_vec gChanLists
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MythMainWindow * GetMythMainWindow(void)
@ kMSStdOut
allow access to stdout
@ kMSRunShell
run process through shell
@ kMSDontDisableDrawing
avoid disabling UI drawing
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
VERBOSE_PREAMBLE Most true
static void IPTVConfigurationGroup(CaptureCard &parent, CardType &cardType)
QMap< QString, VBoxDevice > VBoxDeviceList
static bool is_grabber_external(const QString &grabber)