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;
1829 devs.push_back(it.key());
1830 in_use[it.key()] = (*it).m_inUse;
1833 QString man_addr = VBoxDeviceIDList::tr(
"Manually Enter IP Address");
1834 QString sel = man_addr;
1835 devs.push_back(sel);
1837 for (
const auto & dev : devs)
1838 sel = (
current == dev) ? dev : sel;
1840 QString usestr = QString(
" -- ");
1841 usestr += QObject::tr(
"Warning: already in use");
1843 for (
const auto & dev : devs)
1845 QString desc = dev + (in_use[dev] ? usestr :
"");
1853 else if (sel == man_addr && !
current.isEmpty())
1856 QStringList selection =
current.split(
"-");
1877 if (v == VBoxDeviceIDList::tr(
"Manually Enter IP Address"))
1882 else if (!v.isEmpty())
1884 if (
m_oldValue == VBoxDeviceIDList::tr(
"Manually Enter IP Address"))
1909 setValue(
"http://mafreebox.freebox.fr/freeboxtv/playlist.m3u");
1912 QObject::tr(
"URL of M3U file containing RTSP/RTP/UDP/HTTP channel URLs,"
1913 " example for HDHomeRun: http://<ipv4>/lineup.m3u and for Freebox:"
1914 " http://mafreebox.freebox.fr/freeboxtv/playlist.m3u."
1933 setLabel(QObject::tr(
"ASI device"));
1952 std::stable_sort(sdevs.begin(), sdevs.end());
1961 QMap<QString,bool> in_use;
1963 for (
const QString& dev : std::as_const(sdevs))
1965 in_use[dev] = db.contains(dev);
1966 if (sel.isEmpty() && !in_use[dev])
1971 if (sel.isEmpty() && !sdevs.empty())
1974 QString usestr = QString(
" -- ");
1975 usestr += QObject::tr(
"Warning: already in use");
1979 for (
const QString& dev : std::as_const(sdevs))
1981 QString desc = dev + (in_use[dev] ? usestr :
"");
1982 desc = (
current == dev) ? dev : desc;
1984 found |= (dev == sel);
1988 if (!found && !
current.isEmpty())
1990 QString desc =
current +
" -- " +
1991 QObject::tr(
"Warning: unable to open");
2029 if (device.isEmpty())
2046 LOG(VB_GENERAL, LOG_WARNING,
2047 "ASIConfigurationGroup::probeCard(), Warning: " +
error);
2063 device->setHelpText(tr(
"A local file used to simulate a recording."
2064 " Leave empty to use MythEvents to trigger an"
2065 " external program to import recording files."));
2087 QFileInfo fileInfo(device);
2090 if (device.startsWith(
"file:", Qt::CaseInsensitive))
2091 fileInfo.setFile(device.mid(5));
2093 if (fileInfo.exists())
2095 if (fileInfo.isReadable() && (fileInfo.isFile()))
2098 cs = tr(
"%1 MB").arg(fileInfo.size() / 1024 / 1024);
2102 ci = tr(
"File not readable");
2107 ci = tr(
"File %1 does not exist").arg(device);
2159 for (
const auto & dev : std::as_const(devs))
2161 QStringList devinfo = dev.split(
" ");
2162 const QString&
id = devinfo.at(0);
2163 const QString& ip = devinfo.at(1);
2164 const QString& tunerNo = devinfo.at(2);
2165 const QString& tunerType = devinfo.at(3);
2184 for (
const auto & dev : std::as_const(db))
2186 QMap<QString, VBoxDevice>::iterator dit;
2190 (*dit).m_inUse =
true;
2198CetonSetting::CetonSetting(QString label,
const QString& helptext)
2200 setLabel(std::move(label));
2201 setHelpText(helptext);
2203 this, &CetonSetting::UpdateDevices);
2206void CetonSetting::UpdateDevices(
const QString &v)
2212void CetonSetting::LoadValue(
const QString &value)
2217CetonDeviceID::CetonDeviceID(
const CaptureCard &parent) :
2225CetonDeviceID::~CetonDeviceID()
2227 delete GetStorage();
2230void CetonDeviceID::SetIP(
const QString &ip)
2232 static const QRegularExpression ipV4Regex
2233 {
"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){4}$" };
2234 auto match = ipV4Regex.match(ip +
".");
2235 if (match.hasMatch())
2238 setValue(QString(
"%1-RTP.%3").arg(m_ip, m_tuner));
2242void CetonDeviceID::SetTuner(
const QString &tuner)
2244 static const QRegularExpression oneDigit {
"^\\d$" };
2245 auto match = oneDigit.match(tuner);
2246 if (match.hasMatch())
2249 setValue(QString(
"%1-RTP.%2").arg(m_ip, m_tuner));
2253void CetonDeviceID::Load(
void)
2255 GetStorage()->Load();
2259void CetonDeviceID::UpdateValues(
void)
2261 static const QRegularExpression newstyle { R
"(^([0-9.]+)-(\d|RTP)\.(\d)$)" };
2262 auto match = newstyle.match(getValue());
2263 if (match.hasMatch())
2265 emit LoadedIP(match.captured(1));
2266 emit LoadedTuner(match.captured(3));
2272 auto *deviceid =
new CetonDeviceID(parent);
2274 desc->setLabel(tr(
"CetonConfigurationGroup",
"Description"));
2275 auto *ip =
new CetonSetting(tr(
"IP Address"),
2276 tr(
"IP Address of the Ceton device (192.168.200.1 by default)"));
2277 auto *tuner =
new CetonSetting(tr(
"Tuner"),
2278 tr(
"Number of the tuner on the Ceton device (first tuner is number 0)"));
2287 QObject::connect(ip, &CetonSetting::NewValue,
2288 deviceid, &CetonDeviceID::SetIP);
2289 QObject::connect(tuner, &CetonSetting::NewValue,
2290 deviceid, &CetonDeviceID::SetTuner);
2292 QObject::connect(deviceid, &CetonDeviceID::LoadedIP,
2293 ip, &CetonSetting::LoadValue);
2294 QObject::connect(deviceid, &CetonDeviceID::LoadedTuner,
2295 tuner, &CetonSetting::LoadValue);
2319 const QString &inputtype) :
2325 QRegularExpression drv {
"^(?!ivtv|hdpvr|(saa7164(.*))).*$" };
2349 QString cn = tr(
"Failed to open");
2353 QByteArray adevice = device.toLatin1();
2354 int videofd = open(adevice.constData(), O_RDWR);
2358 ci = cn = tr(
"Failed to probe");
2359 else if (!dn.isEmpty())
2360 ci = cn +
" [" + dn +
"]";
2375 QRegularExpression drv {
"^(ivtv|(saa7164(.*)))$" };
2398 QString cn = tr(
"Failed to open");
2402 QByteArray adevice = device.toLatin1();
2403 int videofd = open(adevice.constData(), O_RDWR);
2407 ci = cn = tr(
"Failed to probe");
2408 else if (!dn.isEmpty())
2409 ci = cn +
" [" + dn +
"]";
2425 device->setHelpText(tr(
"A local MPEG file used to simulate a recording."));
2448 QFileInfo fileInfo(device);
2449 if (fileInfo.exists())
2451 if (fileInfo.isReadable() && (fileInfo.isFile()))
2454 cs = tr(
"%1 MB").arg(fileInfo.size() / 1024 / 1024);
2458 ci = tr(
"File not readable");
2463 ci = tr(
"File does not exist");
2471ExternalConfigurationGroup::ExternalConfigurationGroup(
CaptureCard &a_parent,
2478 device->setLabel(tr(
"Command path"));
2479 device->setHelpText(tr(
"A 'black box' application controlled via stdin, status on "
2480 "stderr and TransportStream read from stdout.\n"
2481 "Use absolute path or path relative to the current directory."));
2491 this, &ExternalConfigurationGroup::probeApp);
2493 probeApp(device->getValue());
2496void ExternalConfigurationGroup::probeApp(
const QString & path)
2498 int idx1 = path.startsWith(
"file:", Qt::CaseInsensitive) ? 5 : 0;
2499 int idx2 = path.indexOf(
' ', idx1);
2502 QFileInfo fileInfo(path.mid(idx1, idx2 - idx1));
2504 if (fileInfo.exists())
2506 ci = tr(
"File '%1' is valid.").arg(fileInfo.absoluteFilePath());
2507 if (!fileInfo.isReadable() || !fileInfo.isFile())
2508 ci = tr(
"WARNING: File '%1' is not readable.")
2509 .arg(fileInfo.absoluteFilePath());
2510 if (!fileInfo.isExecutable())
2511 ci = tr(
"WARNING: File '%1' is not executable.")
2512 .arg(fileInfo.absoluteFilePath());
2516 ci = tr(
"WARNING: File '%1' does not exist.")
2517 .arg(fileInfo.absoluteFilePath());
2520 m_info->setValue(ci);
2521 m_info->setHelpText(ci);
2533 QRegularExpression(
"^hdpvr$"));
2556 QString cn = tr(
"Failed to open");
2560 int videofd = open(device.toLocal8Bit().constData(), O_RDWR);
2564 ci = cn = tr(
"Failed to probe");
2565 else if (!dn.isEmpty())
2566 ci = cn +
" [" + dn +
"]";
2582 setLabel(QObject::tr(
"V4L2 encoder devices (multirec capable)"));
2597 if (!device_name.isEmpty())
2604 QString card_name = tr(
"Failed to open");
2605 QString card_info = card_name;
2624 if (audioinput->fillSelections(device_name) > 1)
2626 audioinput->setName(
"AudioInput");
2639 vbidev->setName(
"VBIDevice");
2657 setLabel(QObject::tr(
"Capture Card Setup"));
2659 auto* cardtype =
new CardType(parent);
2674 new HDHomeRunConfigurationGroup(parent, *cardtype));
2684 new SatIPConfigurationGroup(parent, *cardtype));
2688 FirewireConfigurationGroup(parent, *cardtype);
2692 CetonSetting::CetonConfigurationGroup(parent, *cardtype);
2723 new ExternalConfigurationGroup(parent,
2749 "SELECT cardid, videodevice, cardtype, displayname "
2751 "WHERE hostname = :HOSTNAME AND parentid = 0 "
2765 while (query.
next())
2768 QString videodevice = query.
value(1).toString();
2769 QString cardtype = query.
value(2).toString();
2770 QString displayname = query.
value(3).toString();
2772 QString label = QString(
"%1 (%2)")
2776 card->loadByID(cardid);
2777 card->setLabel(label);
2814 if (dev != init_dev)
2816 if (!init_dev.isEmpty())
2835 for (
uint clone : clones)
2852 setLabel(QObject::tr(
"Card type"));
2853 setHelpText(QObject::tr(
"Change the cardtype to the appropriate type for "
2854 "the capture card you are configuring."));
2862 QObject::tr(
"DVB-T/S/C, ATSC or ISDB-T tuner card"),
"DVB");
2867 QObject::tr(
"V4L2 encoder"),
"V4L2ENC");
2869 QObject::tr(
"HD-PVR H.264 encoder"),
"HDPVR");
2874 QObject::tr(
"HDHomeRun networked tuner"),
"HDHOMERUN");
2879 QObject::tr(
"Sat>IP networked tuner"),
"SATIP");
2884 QObject::tr(
"V@Box TV Gateway networked tuner"),
"VBOX");
2889 QObject::tr(
"FireWire cable box"),
"FIREWIRE");
2894 QObject::tr(
"Ceton Cablecard tuner"),
"CETON");
2898 setting->
addSelection(QObject::tr(
"IPTV recorder"),
"FREEBOX");
2903 QObject::tr(
"Analog to MPEG-2 encoder card (PVR-150/250/350, etc)"),
"MPEG");
2905 QObject::tr(
"Analog to MJPEG encoder card (Matrox G200, DC10, etc)"),
"MJPEG");
2907 QObject::tr(
"Analog to MPEG-4 encoder (Plextor ConvertX USB, etc)"),
2910 QObject::tr(
"Analog capture card"),
"V4L");
2914 setting->
addSelection(QObject::tr(
"DVEO ASI recorder"),
"ASI");
2917 setting->
addSelection(QObject::tr(
"Import test recorder"),
"IMPORT");
2918 setting->
addSelection(QObject::tr(
"Demo test recorder"),
"DEMO");
2920 setting->
addSelection(QObject::tr(
"External (black box) recorder"),
2943 setLabel(QObject::tr(
"Input name"));
2959 addSelection(QObject::tr(
"(None)"),
"None");
2961 if (storage ==
nullptr)
2968 while (!inputs.isEmpty())
2970 addSelection(inputs.front());
2981 setLabel(QObject::tr(
"Delivery system"));
2983 "This shows the delivery system (modulation), for instance DVB-T2, "
2984 "that you have selected when you configured the capture card. "
2985 "This must be the same as the modulation used by the video source. "));
2997 setLabel(QObject::tr(
"Display name"));
2999 "This name is displayed on screen when Live TV begins "
3000 "and in various other places. Make sure the last two "
3001 "characters are unique for each input or use a "
3002 "slash ('/') to designate the unique portion."));
3038 setLabel(QObject::tr(
"Video source"));
3039 addSelection(QObject::tr(
"(None)"),
"0");
3050 addSelection(QObject::tr(
"(None)"),
"0");
3059 m_cardInput(parent),
3060 m_groupNum(group_num)
3062 setLabel(QObject::tr(
"Input group") +
3063 QString(
" %1").arg(m_groupNum + 1));
3065 "Leave as 'Generic' unless this input is shared with "
3066 "another device. Only one of the inputs in an input "
3067 "group will be allowed to record at any given time."));
3070 void Load(
void)
override;
3074 uint inputid = m_cardInput.getInputID();
3077 if (m_groupId && (m_groupId != new_groupid))
3095 LOG(VB_GENERAL, LOG_DEBUG, QString(
"InputGroup::Load() %1 %2")
3096 .arg(m_groupNum).arg(m_cardInput.getInputID()));
3099 uint inputid = m_cardInput.getInputID();
3100 QMap<uint, uint> grpcnt;
3101 std::vector<QString> names;
3102 std::vector<uint> grpid;
3103 std::vector<uint> selected_groupids;
3105 names.push_back(QObject::tr(
"Generic"));
3111 "SELECT cardinputid, inputgroupid, inputgroupname "
3113 "WHERE inputgroupname LIKE 'user:%' "
3114 "ORDER BY inputgroupid, cardinputid, inputgroupname");
3122 while (query.
next())
3125 if ((inputid != 0U) && (query.
value(0).toUInt() == inputid))
3126 selected_groupids.push_back(groupid);
3130 if (grpcnt[groupid] == 1)
3132 names.push_back(query.
value(2).toString().mid(5, -1));
3133 grpid.push_back(groupid);
3140 if (m_groupNum < selected_groupids.size())
3141 m_groupId = selected_groupids[m_groupNum];
3144 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Group num: %1 id: %2")
3145 .arg(m_groupNum).arg(m_groupId));
3148 for (
uint i = 0; i < selected_groupids.size(); i++)
3149 msg += QString(
"%1 ").arg(selected_groupids[i]);
3150 LOG(VB_GENERAL, LOG_DEBUG, msg);
3157 for (
size_t i = 0; i < names.size(); i++)
3159 bool sel = (m_groupId == grpid[i]);
3160 index = sel ? i : index;
3163 LOG(VB_GENERAL, LOG_DEBUG, QString(
"grpid %1, name '%2', i %3, s %4")
3164 .arg(grpid[i]).arg(names[i]) .arg(index).arg(sel ?
"T" :
"F"));
3167 addSelection(names[i], QString::number(grpid[i]), sel);
3171 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Group index: %1").arg(index));
3186 setLabel(QObject::tr(
"Use quick tuning"));
3187 addSelection(QObject::tr(
"Never"),
"0",
true);
3188 addSelection(QObject::tr(
"Live TV only"),
"1",
false);
3189 addSelection(QObject::tr(
"Always"),
"2",
false);
3191 "If enabled, MythTV will tune using only the "
3192 "MPEG program number. The program numbers "
3193 "change more often than DVB or ATSC tuning "
3194 "parameters, so this is slightly less reliable. "
3195 "This will also inhibit EIT gathering during "
3196 "Live TV and recording."));
3206 setLabel(QObject::tr(
"External channel change command"));
3208 setHelpText(QObject::tr(
"If specified, this command will be run to "
3209 "change the channel for inputs which have an external "
3210 "tuner device such as a cable box. The first argument "
3211 "will be the channel number."));
3226 setLabel(QObject::tr(
"Preset tuner to channel"));
3228 setHelpText(QObject::tr(
"Leave this blank unless you have an external "
3229 "tuner that is connected to the tuner input of your card. "
3230 "If so, you will need to specify the preset channel for "
3231 "the signal (normally 3 or 4)."));
3243 if (sourceid.isEmpty() || !sourceid.toUInt())
3248 if (storage ==
nullptr)
3255 if (channels.empty())
3257 addSelection(tr(
"Please add channels to this source"),
3258 startChan.isEmpty() ?
"0" : startChan);
3266 bool has_visible =
false;
3267 for (
size_t i = 0; i < channels.size() && !has_visible; i++)
3270 for (
auto & channel : channels)
3272 const QString channum = channel.m_chanNum;
3273 bool sel = channum == startChan;
3274 if (!has_visible || channel.m_visible || sel)
3276 addSelection(channum, channum, sel);
3288 setLabel(QObject::tr(
"Input priority"));
3290 setHelpText(QObject::tr(
"If the input priority is not equal for "
3291 "all inputs, the scheduler may choose to record a show "
3292 "at a later time so that it can record on an input with "
3293 "a higher value."));
3309 setLabel(QObject::tr(
"Schedule order"));
3311 setHelpText(QObject::tr(
"If priorities and other factors are equal "
3312 "the scheduler will choose the available "
3313 "input with the lowest, non-zero value. "
3314 "Setting this value to zero will make the "
3315 "input unavailable to the scheduler."));
3331 setLabel(QObject::tr(
"Live TV order"));
3333 setHelpText(QObject::tr(
"When entering Live TV, the available, local "
3334 "input with the lowest, non-zero value will "
3335 "be used. If no local inputs are available, "
3336 "the available, remote input with the lowest, "
3337 "non-zero value will be used. "
3338 "Setting this value to zero will make the "
3339 "input unavailable to live TV."));
3355 setLabel(QObject::tr(
"Use DishNet long-term EIT data"));
3359 "If you point your satellite dish toward DishNet's birds, "
3360 "you may wish to enable this feature. For best results, "
3361 "enable general EIT collection as well."));
3392 if (
"DVB" == cardtype)
3414 if (
"DVB" == cardtype)
3419 tr(
"Use channel scanner to find channels for this input."));
3422 tr(
"This uses the listings data source to "
3423 "provide the channels for this input.") +
" " +
3424 tr(
"This can take a long time to run."));
3433 interact->setLabel(QObject::tr(
"Interactions between inputs"));
3443 interact->addChild(
new LiveTVOrder(*
this, _cardid));
3447 ingrpbtn->setHelpText(
3448 QObject::tr(
"Input groups are only needed when two or more cards "
3449 "share the same resource such as a FireWire card and "
3450 "an analog card input controlling the same set top box."));
3451 interact->addChild(ingrpbtn);
3457 setObjectName(
"CardInput");
3483 bool enable = (sourceid.toInt() > 0);
3500 auto *settingdialog =
3503 if (settingdialog->Create())
3511 delete settingdialog;
3519 ShowOkPopup(tr(
"Sorry, this Input Group name cannot be blank."));
3523 QString new_name = QString(
"user:") + name;
3526 query.
prepare(
"SELECT inputgroupname "
3528 "WHERE inputgroupname = :GROUPNAME");
3529 query.
bindValue(
":GROUPNAME", new_name);
3539 ShowOkPopup(tr(
"Sorry, this Input Group name is already in use."));
3574 LOG(VB_GENERAL, LOG_ERR,
3575 QString(
"Sorry, %1 cards do not yet support scanning.")
3587 [srcid,
this, num_channels_before]()
3591 if (num_channels_before)
3605 LOG(VB_GENERAL, LOG_ERR,
"You must compile the backend "
3606 "to be able to scan for channels");
3626 cardtype !=
"HDHOMERUN" &&
3627 !num_channels_before)
3629 LOG(VB_GENERAL, LOG_ERR,
"Skipping channel fetch, you need to "
3630 "scan for channels first.");
3639 if (num_channels_before)
3648 QString cardinputidTag(
":WHERECARDID");
3650 QString query(
"cardid = " + cardinputidTag);
3659 QString cardinputidTag(
":SETCARDID");
3662 QString query(
"cardid = " + cardinputidTag +
", " +
3681 query.
prepare(
"SELECT cardid FROM capturecard "
3682 "WHERE cardid = :CARDID AND inputname = :INPUTNAME");
3684 query.
bindValue(
":INPUTNAME", _inputname);
3737 tr(
"Are you sure you want to delete "
3746 tr(
"Are you sure you want to delete "
3747 "ALL capture cards?"),
3755 card->setLabel(tr(
"New capture card"));
3781 "WHERE hostname = :HOSTNAME");
3787 tr(
"Error getting list of cards for this host. "
3788 "Unable to delete capturecards for %1")
3795 while (cards.
next())
3811 AddSelection(QObject::tr(
"(Delete all capture cards on %1)")
3814 AddSelection(QObject::tr(
"(Delete all capture cards)"),
3828 AddSelection(QObject::tr(
"(Delete all video sources)"),
3851 tr(
"Are you sure you want to delete "
3852 "ALL video sources?"),
3870 source->setLabel(tr(
"New video source"));
3892 "SELECT cardid, videodevice, cardtype, displayname "
3894 "WHERE hostname = :HOSTNAME "
3895 " AND parentid = 0 "
3905 while (query.
next())
3908 QString videodevice = query.
value(1).toString();
3909 QString cardtype = query.
value(2).toString();
3910 QString displayname = query.
value(3).toString();
3912 auto *cardinput =
new CardInput(cardtype, videodevice, cardid);
3913 cardinput->loadByID(cardid);
3914 QString inputlabel = QString(
"%1 (%2) -> %3")
3916 displayname, cardinput->getSourceName());
3918 cardinput->setLabel(inputlabel);
3926static QString remove_chaff(
const QString &name)
3929 QString short_name = name;
3930 if (short_name.startsWith(
"LG Electronics"))
3931 short_name = short_name.right(short_name.length() - 15);
3932 if (short_name.startsWith(
"Oren"))
3933 short_name = short_name.right(short_name.length() - 5);
3934 if (short_name.startsWith(
"Nextwave"))
3935 short_name = short_name.right(short_name.length() - 9);
3936 if (short_name.startsWith(
"frontend", Qt::CaseInsensitive))
3937 short_name = short_name.left(short_name.length() - 9);
3938 if (short_name.endsWith(
"VSB/QAM"))
3939 short_name = short_name.left(short_name.length() - 8);
3940 if (short_name.endsWith(
"VSB"))
3941 short_name = short_name.left(short_name.length() - 4);
3942 if (short_name.endsWith(
"DVB-T"))
3943 short_name = short_name.left(short_name.length() - 6);
3949 short_name = short_name.simplified();
3950 if (short_name.startsWith(
"or51211", Qt::CaseInsensitive))
3951 short_name =
"pcHDTV HD-2000";
3952 else if (short_name.startsWith(
"or51132", Qt::CaseInsensitive))
3953 short_name =
"pcHDTV HD-3000";
3954 else if (short_name.startsWith(
"bcm3510", Qt::CaseInsensitive))
3955 short_name =
"Air2PC v1";
3956 else if (short_name.startsWith(
"nxt2002", Qt::CaseInsensitive) ||
3957 short_name.startsWith(
"nxt200x", Qt::CaseInsensitive))
3958 short_name =
"Air2PC v2";
3959 else if (short_name.startsWith(
"lgdt3302", Qt::CaseInsensitive))
3960 short_name =
"DViCO HDTV3";
3961 else if (short_name.startsWith(
"lgdt3303", Qt::CaseInsensitive))
3962 short_name =
"DViCO v2 or Air2PC v3 or pcHDTV HD-5500";
3987 if (videodevice.isEmpty())
4005 QString err_open = tr(
"Could not open card %1").arg(videodevice);
4006 QString err_other = tr(
"Could not get card info for card %1").arg(videodevice);
4052 if (frontend_name.toLower().indexOf(
"usb") >= 0)
4059 if ((frontend_name ==
"DiBcom 3000P/M-C DVB-T") ||
4061 "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"))
4067 QString short_name = remove_chaff(frontend_name);
4068 m_buttonAnalog->setVisible(
4069 short_name.startsWith(
"zarlink zl10353",
4070 Qt::CaseInsensitive) ||
4071 short_name.startsWith(
"wintv hvr 900 m/r: 65008/a1c0",
4072 Qt::CaseInsensitive) ||
4073 short_name.startsWith(
"philips tda10046h",
4074 Qt::CaseInsensitive));
4080 QString short_name = remove_chaff(frontend_name);
4088 if (frontend_name ==
"Nextwave NXT200X VSB/QAM frontend")
4095 if (frontend_name.toLower().indexOf(
"usb") < 0)
4097 m_buttonAnalog->setVisible(
4098 short_name.startsWith(
"pchdtv", Qt::CaseInsensitive) ||
4099 short_name.startsWith(
"dvico", Qt::CaseInsensitive) ||
4100 short_name.startsWith(
"nextwave", Qt::CaseInsensitive));
4113 for (
const auto & item : std::as_const(delsyslist))
4115 LOG(VB_GENERAL, LOG_DEBUG, QString(
"DVBCardType: add deliverysystem:%1")
4123 if (!delsys.isEmpty())
4135 QString dev, QString
type) :
4137 m_lastDevice(std::move(dev)), m_lastCardType(std::move(
type))
4139 setLabel(QObject::tr(
"Audio input"));
4140 setHelpText(QObject::tr(
"If there is more than one audio input, "
4141 "select which one to use."));
4154 if (device.isEmpty())
4158 QStringList inputs =
4161 for (
uint i = 0; i < (
uint)inputs.size(); i++)
4166 return inputs.size();
4249 explicit DiSEqCPosition(
const CaptureCard &parent,
int value,
int min_val) :
4253 setLabel(QObject::tr(
"DiSEqC position"));
4254 setHelpText(QObject::tr(
"Position of the LNB on the DiSEqC switch. "
4255 "Leave at 1 if there is no DiSEqC switch "
4256 "and the LNB is directly connected to the SatIP server. "
4257 "This value is used as signal source (attribute src) in "
4258 "the SatIP tune command."));
4262 ~DiSEqCPosition()
override
4268SatIPConfigurationGroup::SatIPConfigurationGroup
4271 m_deviceId(new SatIPDeviceID(a_parent))
4277 m_friendlyName =
new SatIPDeviceAttribute(tr(
"Friendly name"), tr(
"Friendly name of the Sat>IP server"));
4278 m_tunerType =
new SatIPDeviceAttribute(tr(
"Tuner type"), tr(
"Type of the selected tuner"));
4279 m_tunerIndex =
new SatIPDeviceAttribute(tr(
"Tuner index"), tr(
"Index of the tuner on the Sat>IP server"));
4281 m_deviceIdList =
new SatIPDeviceIDList(
4282 m_deviceId, m_friendlyName, m_tunerType, m_tunerIndex, &m_deviceList,
m_parent);
4294 connect(m_deviceIdList, &SatIPDeviceIDList::NewTuner,
4295 m_deviceId, &SatIPDeviceID::SetTuner);
4298void SatIPConfigurationGroup::FillDeviceList(
void)
4300 m_deviceList.clear();
4306 for (
const auto & dev : std::as_const(devs))
4308 QStringList devparts = dev.split(
" ");
4309 const QString&
id = devparts.value(0);
4310 const QString& name = devparts.value(1);
4311 const QString& ip = devparts.value(2);
4312 const QString& tunerno = devparts.value(3);
4313 const QString& tunertype = devparts.value(4);
4316 device.m_deviceId = id;
4317 device.m_cardIP = ip;
4318 device.m_inUse =
false;
4319 device.m_friendlyName = name;
4320 device.m_tunerNo = tunerno;
4321 device.m_tunerType = tunertype;
4322 device.m_mythDeviceId = QString(
"%1:%2:%3").arg(
id, tunertype, tunerno);
4324 QString friendlyIdentifier = QString(
"%1, %2, Tuner #%3").arg(name, tunertype, tunerno);
4326 m_deviceList[device.m_mythDeviceId] = device;
4328 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"SatIP: Add %1 '%2' '%3'")
4329 .arg(device.m_mythDeviceId, device.m_friendlyName, friendlyIdentifier));
4335 for (
const auto& dev : std::as_const(db))
4337 auto dit = m_deviceList.find(dev);
4338 if (dit != m_deviceList.end())
4340 (*dit).m_inUse =
true;
4345SatIPDeviceIDList::SatIPDeviceIDList(
4346 SatIPDeviceID *deviceId,
4347 SatIPDeviceAttribute *friendlyName,
4348 SatIPDeviceAttribute *tunerType,
4349 SatIPDeviceAttribute *tunerIndex,
4350 SatIPDeviceList *deviceList,
4352 m_deviceId(deviceId),
4353 m_friendlyName(friendlyName),
4354 m_tunerType(tunerType),
4355 m_tunerIndex(tunerIndex),
4356 m_deviceList(deviceList),
4360 setHelpText(tr(
"Device IP or ID, tuner number and tuner type of available Sat>IP device"));
4363 this, &SatIPDeviceIDList::UpdateDevices);
4366void SatIPDeviceIDList::Load(
void)
4370 int cardid = m_parent.getCardID();
4373 fillSelections(device);
4376void SatIPDeviceIDList::UpdateDevices(
const QString &v)
4378 SatIPDevice dev = (*m_deviceList)[v];
4379 m_deviceId->setValue(dev.m_mythDeviceId);
4380 m_friendlyName->setValue(dev.m_friendlyName);
4381 m_tunerType->setValue(dev.m_tunerType);
4382 m_tunerIndex->setValue(dev.m_tunerNo);
4385void SatIPDeviceIDList::fillSelections(
const QString &cur)
4389 std::vector<QString> names;
4390 std::vector<QString> devs;
4391 QMap<QString, bool> in_use;
4396 names.reserve(m_deviceList->size());
4397 devs.reserve(m_deviceList->size());
4398 SatIPDeviceList::iterator it = m_deviceList->begin();
4399 for(; it != m_deviceList->end(); ++it)
4401 QString friendlyIdentifier = QString(
"%1, %2, Tuner #%3")
4402 .arg((*it).m_friendlyName, (*it).m_tunerType, (*it).m_tunerNo);
4403 names.push_back(friendlyIdentifier);
4405 devs.push_back(it.key());
4406 in_use[it.key()] = (*it).m_inUse;
4409 for (
const auto& it2s : devs)
4411 sel = (
current == it2s) ? it2s : sel;
4414 QString usestr = QString(
" -- ");
4415 usestr += tr(
"Warning: already in use");
4417 for (
uint i = 0; i < devs.size(); ++i)
4419 const QString& dev = devs[i];
4420 const QString& name = names[i];
4421 bool dev_in_use = (dev == sel) ?
false : in_use[devs[i]];
4422 QString desc = name + (dev_in_use ? usestr :
"");
4423 addSelection(desc, dev, dev == sel);
4427SatIPDeviceID::SatIPDeviceID(
const CaptureCard &parent) :
4437SatIPDeviceID::~SatIPDeviceID()
4439 delete GetStorage();
4442void SatIPDeviceID::Load(
void)
4447void SatIPDeviceID::SetTuner(
const QString &tuner)
4452SatIPDeviceAttribute::SatIPDeviceAttribute(
const QString& label,
const QString& helptext)
4455 setHelpText(helptext);
4459#include "moc_videosource.cpp"
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)