MythTV  master
channeldata.cpp
Go to the documentation of this file.
1 // C++ headers
2 #include <cstdlib>
3 #include <iostream>
4 
5 // Qt headers
6 #include <QDir>
7 #include <QFile>
8 #include <QRegularExpression>
9 
10 // MythTV headers
11 #include "libmythbase/mythdb.h"
15 #include "libmythtv/cardutil.h"
16 #include "libmythtv/channelutil.h"
18 #include "libmythtv/sourceutil.h"
19 
20 // filldata headers
21 #include "channeldata.h"
22 #include "fillutil.h"
23 
24 #if QT_VERSION < QT_VERSION_CHECK(5,15,2)
25 #define capturedView capturedRef
26 #endif
27 
28 static const QRegularExpression parseMajorMinor { R"((\d+)\D(\d+))" };
29 
30 static void get_atsc_stuff(const QString& channum, int sourceid, int freqid,
31  int &major, int &minor, long long &freq)
32 {
33  major = freqid;
34  minor = 0;
35 
36  auto match = parseMajorMinor.match(channum);
37  if (!match.hasMatch())
38  return;
39 
40  major = match.capturedView(1).toInt();
41  minor = match.capturedView(2).toInt();
42 
43  freq = get_center_frequency("atsc", "vsb8", "us", freqid);
44 
45  // Check if this is connected to an HDTV card.
47  query.prepare(
48  "SELECT cardtype "
49  "FROM capturecard "
50  "WHERE sourceid = :SOURCEID");
51  query.bindValue(":SOURCEID", sourceid);
52 
53  if (query.exec() && query.isActive() && query.next() &&
54  query.value(0).toString() == "HDTV")
55  {
56  freq -= 1750000; // convert to visual carrier freq.
57  }
58 }
59 
60 bool ChannelData::insert_chan(uint sourceid) const
61 {
62  bool insert_channels = m_channelUpdates;
63  if (!insert_channels)
64  {
65  bool isEncoder = false;
66  bool isUnscanable = false;
67  bool isCableCard = SourceUtil::IsCableCardPresent(sourceid);
68  if (m_cardType.isEmpty())
69  {
70  isEncoder = SourceUtil::IsEncoder(sourceid);
71  isUnscanable = SourceUtil::IsUnscanable(sourceid);
72  }
73  else
74  {
75  isEncoder = CardUtil::IsEncoder(m_cardType);
76  isUnscanable = CardUtil::IsUnscanable(m_cardType);
77  }
78  insert_channels = (isCableCard || isEncoder || isUnscanable);
79  }
80 
81  return insert_channels;
82 }
83 
84 
86  ChannelInfoList::iterator chaninfo, unsigned int chanid) const
87 {
88  (*chaninfo).m_name = getResponse(QObject::tr("Choose a channel name (any string, "
89  "long version) "),(*chaninfo).m_name);
90  (*chaninfo).m_callSign = getResponse(QObject::tr("Choose a channel callsign (any string, "
91  "short version) "),(*chaninfo).m_callSign);
92 
93  if (m_channelPreset)
94  {
95  (*chaninfo).m_chanNum = getResponse(QObject::tr("Choose a channel preset (0..999) "),
96  (*chaninfo).m_chanNum);
97  (*chaninfo).m_freqId = getResponse(QObject::tr("Choose a frequency id "),
98  (*chaninfo).m_freqId);
99  }
100  else
101  {
102  (*chaninfo).m_chanNum = getResponse(QObject::tr("Choose a channel number "),
103  (*chaninfo).m_chanNum);
104  (*chaninfo).m_freqId = (*chaninfo).m_chanNum;
105  }
106 
107  (*chaninfo).m_fineTune = getResponse(QObject::tr("Choose a channel fine tune offset "),
108  QString::number((*chaninfo).m_fineTune)).toInt();
109 
110  (*chaninfo).m_tvFormat = getResponse(QObject::tr("Choose a TV format "
111  "(PAL/SECAM/NTSC/ATSC/Default) "),
112  (*chaninfo).m_tvFormat);
113 
114  (*chaninfo).m_icon = getResponse(QObject::tr("Choose a channel icon image "
115  "(relative path to icon storage group) "),
116  (*chaninfo).m_icon);
117 
118  return(chanid);
119 }
120 
121 QString ChannelData::normalizeChannelKey(const QString &chanName)
122 {
123  QString result = chanName;
124 
125  // Lowercase
126  result = result.toLower();
127  // Strip all whitespace
128  result = result.replace(" ", "");
129 
130  return result;
131 }
132 
134 {
135  ChannelList retList;
136 
137  uint avail = 0;
141  sourceId, 0,
142  false, "", "",
143  false);
144 
145  for (auto & channel : channelList)
146  {
147  QString chanName = channel.m_name;
148  QString key = normalizeChannelKey(chanName);
149  retList.insert(key, channel);
150  }
151 
152  return retList;
153 }
154 
156  ChannelList existingChannels)
157 {
158  ChannelList::iterator it;
159  for (it = existingChannels.begin(); it != existingChannels.end(); ++it)
160  {
161  if ((*it).m_xmltvId == chanInfo.m_xmltvId)
162  return (*it);
163  }
164 
165  QString searchKey = normalizeChannelKey(chanInfo.m_name);
166  ChannelInfo existChan = existingChannels.value(searchKey);
167 
168  if (existChan.m_chanId < 1)
169  {
170  // Check if it is ATSC
171  auto match = parseMajorMinor.match(chanInfo.m_chanNum);
172  if (match.hasMatch())
173  {
174  // Populate xmltvid for scanned ATSC channels
175  uint major = match.capturedView(1).toUInt();
176  uint minor = match.capturedView(2).toUInt();
177 
178  for (it = existingChannels.begin();
179  it != existingChannels.end(); ++it)
180  {
181  if ((*it).m_atscMajorChan == major &&
182  (*it).m_atscMinorChan == minor)
183  return (*it);
184  }
185  }
186  }
187 
188  return existChan;
189 }
190 
191 void ChannelData::handleChannels(int id, ChannelInfoList *chanlist) const
192 {
193  if (m_guideDataOnly)
194  {
195  LOG(VB_GENERAL, LOG_NOTICE, "Skipping Channel Updates");
196  return;
197  }
198 
199  ChannelList existingChannels = channelList(id);
200  QString fileprefix = SetupIconCacheDirectory();
201 
202  QDir::setCurrent(fileprefix);
203 
204  fileprefix += "/";
205 
206  bool insertChan = insert_chan(id); // unscannable source
207 
208  auto i = chanlist->begin();
209  for (; i != chanlist->end(); ++i)
210  {
211  if ((*i).m_xmltvId.isEmpty())
212  continue;
213 
214  QString localfile;
215 
216  if (!(*i).m_icon.isEmpty())
217  {
218  QDir remotefile = QDir((*i).m_icon);
219  QString filename = remotefile.dirName();
220 
221  localfile = fileprefix + filename;
222  QFile actualfile(localfile);
223  if (!actualfile.exists() &&
224  !GetMythDownloadManager()->download((*i).m_icon, localfile))
225  {
226  LOG(VB_GENERAL, LOG_ERR,
227  QString("Failed to fetch icon from '%1'")
228  .arg((*i).m_icon));
229  }
230 
231  localfile = filename;
232  }
233 
234  MSqlQuery query(MSqlQuery::InitCon());
235 
236  if (!(*i).m_oldXmltvId.isEmpty())
237  {
238  query.prepare(
239  "SELECT xmltvid "
240  "FROM channel "
241  "WHERE xmltvid = :XMLTVID");
242  query.bindValue(":XMLTVID", (*i).m_oldXmltvId);
243 
244  if (!query.exec())
245  {
246  MythDB::DBError("xmltvid conversion 1", query);
247  }
248  else if (query.next())
249  {
250  LOG(VB_GENERAL, LOG_INFO,
251  QString("Converting old xmltvid (%1) to new (%2)")
252  .arg((*i).m_oldXmltvId, (*i).m_xmltvId));
253 
254  query.prepare("UPDATE channel "
255  "SET xmltvid = :NEWXMLTVID"
256  "WHERE xmltvid = :OLDXMLTVID");
257  query.bindValue(":NEWXMLTVID", (*i).m_xmltvId);
258  query.bindValue(":OLDXMLTVID", (*i).m_oldXmltvId);
259 
260  if (!query.exec())
261  {
262  MythDB::DBError("xmltvid conversion 2", query);
263  }
264  }
265  }
266 
267  ChannelInfo dbChan = FindMatchingChannel(*i, existingChannels);
268  if (dbChan.m_chanId > 0) // Channel exists, updating
269  {
270  LOG(VB_XMLTV, LOG_DEBUG,
271  QString("Match found for xmltvid %1 to channel %2 (%3)")
272  .arg((*i).m_xmltvId, dbChan.m_name, QString::number(dbChan.m_chanId)));
273  if (m_interactive)
274  {
275 
276  std::cout << "### " << std::endl;
277  std::cout << "### Existing channel found" << std::endl;
278  std::cout << "### " << std::endl;
279  std::cout << "### xmltvid = "
280  << (*i).m_xmltvId.toLocal8Bit().constData() << std::endl;
281  std::cout << "### chanid = "
282  << dbChan.m_chanId << std::endl;
283  std::cout << "### name = "
284  << dbChan.m_name.toLocal8Bit().constData() << std::endl;
285  std::cout << "### callsign = "
286  << dbChan.m_callSign.toLocal8Bit().constData() << std::endl;
287  std::cout << "### channum = "
288  << dbChan.m_chanNum.toLocal8Bit().constData() << std::endl;
289  if (m_channelPreset)
290  {
291  std::cout << "### freqid = "
292  << dbChan.m_freqId.toLocal8Bit().constData() << std::endl;
293  }
294  std::cout << "### finetune = "
295  << dbChan.m_fineTune << std::endl;
296  std::cout << "### tvformat = "
297  << dbChan.m_tvFormat.toLocal8Bit().constData() << std::endl;
298  std::cout << "### icon = "
299  << dbChan.m_icon.toLocal8Bit().constData() << std::endl;
300  std::cout << "### " << std::endl;
301 
302  // The only thing the xmltv data supplies here is the icon
303  (*i).m_name = dbChan.m_name;
304  (*i).m_callSign = dbChan.m_callSign;
305  (*i).m_chanNum = dbChan.m_chanNum;
306  (*i).m_fineTune = dbChan.m_fineTune;
307  (*i).m_freqId = dbChan.m_freqId;
308  (*i).m_tvFormat = dbChan.m_tvFormat;
309 
311 
312  if ((*i).m_callSign.isEmpty())
313  (*i).m_callSign = dbChan.m_name;
314 
315  if (dbChan.m_name != (*i).m_name ||
316  dbChan.m_callSign != (*i).m_callSign ||
317  dbChan.m_chanNum != (*i).m_chanNum ||
318  dbChan.m_fineTune != (*i).m_fineTune ||
319  dbChan.m_freqId != (*i).m_freqId ||
320  dbChan.m_icon != localfile ||
321  dbChan.m_tvFormat != (*i).m_tvFormat)
322  {
323  MSqlQuery subquery(MSqlQuery::InitCon());
324  subquery.prepare("UPDATE channel SET chanid = :CHANID, "
325  "name = :NAME, callsign = :CALLSIGN, "
326  "channum = :CHANNUM, finetune = :FINE, "
327  "icon = :ICON, freqid = :FREQID, "
328  "tvformat = :TVFORMAT "
329  " WHERE xmltvid = :XMLTVID "
330  "AND sourceid = :SOURCEID;");
331  subquery.bindValue(":CHANID", dbChan.m_chanId);
332  subquery.bindValue(":NAME", (*i).m_name);
333  subquery.bindValue(":CALLSIGN", (*i).m_callSign);
334  subquery.bindValue(":CHANNUM", (*i).m_chanNum);
335  subquery.bindValue(":FINE", (*i).m_fineTune);
336  subquery.bindValue(":ICON", localfile);
337  subquery.bindValue(":FREQID", (*i).m_freqId);
338  subquery.bindValue(":TVFORMAT", (*i).m_tvFormat);
339  subquery.bindValue(":XMLTVID", (*i).m_xmltvId);
340  subquery.bindValue(":SOURCEID", id);
341 
342  if (!subquery.exec())
343  {
344  MythDB::DBError("update failed", subquery);
345  }
346  else
347  {
348  std::cout << "### " << std::endl;
349  std::cout << "### Change performed" << std::endl;
350  std::cout << "### " << std::endl;
351  }
352  }
353  else
354  {
355  std::cout << "### " << std::endl;
356  std::cout << "### Nothing changed" << std::endl;
357  std::cout << "### " << std::endl;
358  }
359  }
360  else if ((dbChan.m_icon != localfile) ||
361  (dbChan.m_xmltvId != (*i).m_xmltvId))
362  {
363  LOG(VB_XMLTV, LOG_NOTICE, QString("Updating channel %1 (%2)")
364  .arg(dbChan.m_name).arg(dbChan.m_chanId));
365 
366  if (localfile.isEmpty())
367  localfile = dbChan.m_icon;
368 
369  if (dbChan.m_xmltvId != (*i).m_xmltvId)
370  {
371  MSqlQuery subquery(MSqlQuery::InitCon());
372 
373  subquery.prepare("UPDATE channel SET icon = :ICON "
374  ", xmltvid:= :XMLTVID WHERE "
375  "chanid = :CHANID;");
376  subquery.bindValue(":ICON", localfile);
377  subquery.bindValue(":XMLTVID", (*i).m_xmltvId);
378  subquery.bindValue(":CHANID", dbChan.m_chanId);
379 
380  if (!subquery.exec())
381  MythDB::DBError("Channel icon change", subquery);
382  }
383  else
384  {
385  MSqlQuery subquery(MSqlQuery::InitCon());
386  subquery.prepare("UPDATE channel SET icon = :ICON WHERE "
387  "chanid = :CHANID;");
388  subquery.bindValue(":ICON", localfile);
389  subquery.bindValue(":CHANID", dbChan.m_chanId);
390 
391  if (!subquery.exec())
392  MythDB::DBError("Channel icon change", subquery);
393  }
394 
395  }
396  }
397  else if (insertChan) // Only insert channels for non-scannable sources
398  {
399  int major = 0;
400  int minor = 0;
401  long long freq = 0;
402  get_atsc_stuff((*i).m_chanNum, id, (*i).m_freqId.toInt(), major, minor, freq);
403 
404  if (m_interactive && ((minor == 0) || (freq > 0)))
405  {
406  std::cout << "### " << std::endl;
407  std::cout << "### New channel found" << std::endl;
408  std::cout << "### " << std::endl;
409  std::cout << "### name = "
410  << (*i).m_name.toLocal8Bit().constData() << std::endl;
411  std::cout << "### callsign = "
412  << (*i).m_callSign.toLocal8Bit().constData() << std::endl;
413  std::cout << "### channum = "
414  << (*i).m_chanNum.toLocal8Bit().constData() << std::endl;
415  if (m_channelPreset)
416  {
417  std::cout << "### freqid = "
418  << (*i).m_freqId.toLocal8Bit().constData() << std::endl;
419  }
420  std::cout << "### finetune = "
421  << (*i).m_fineTune << std::endl;
422  std::cout << "### tvformat = "
423  << (*i).m_tvFormat.toLocal8Bit().constData() << std::endl;
424  std::cout << "### icon = "
425  << localfile.toLocal8Bit().constData() << std::endl;
426  std::cout << "### " << std::endl;
427 
428  uint chanid = promptForChannelUpdates(i,0);
429 
430  if ((*i).m_callSign.isEmpty())
431  (*i).m_callSign = QString::number(chanid);
432 
433  int mplexid = 0;
434  if ((chanid > 0) && (minor > 0))
435  mplexid = ChannelUtil::CreateMultiplex(id, "atsc",
436  freq, "8vsb");
437 
438  if (((mplexid > 0) || ((minor == 0) && (chanid > 0))) &&
440  mplexid, id, chanid,
441  (*i).m_callSign, (*i).m_name, (*i).m_chanNum,
442  0 /*service id*/, major, minor,
443  false /*use on air guide*/, kChannelVisible,
444  (*i).m_freqId, localfile, (*i).m_tvFormat,
445  (*i).m_xmltvId))
446  {
447  std::cout << "### " << std::endl;
448  std::cout << "### Channel inserted" << std::endl;
449  std::cout << "### " << std::endl;
450  }
451  else
452  {
453  std::cout << "### " << std::endl;
454  std::cout << "### Channel skipped" << std::endl;
455  std::cout << "### " << std::endl;
456  }
457  }
458  else if ((minor == 0) || (freq > 0))
459  {
460  // We only do this if we are not asked to skip it with the
461  // --update-guide-only (formerly --update) flag.
462  int mplexid = 0;
463  int chanid = 0;
464  if (minor > 0)
465  {
467  id, "atsc", freq, "8vsb");
468  }
469 
470  if ((mplexid > 0) || (minor == 0))
471  chanid = ChannelUtil::CreateChanID(id, (*i).m_chanNum);
472 
473  if ((*i).m_callSign.isEmpty())
474  {
475  QStringList words = (*i).m_name.simplified().toUpper()
476  .split(" ");
477  QString callsign = "";
478  QString w1 = !words.empty() ? words[0] : QString();
479  QString w2 = words.size() > 1 ? words[1] : QString();
480  if (w1.isEmpty())
481  callsign = QString::number(chanid);
482  else if (w2.isEmpty())
483  callsign = words[0].left(5);
484  else
485  {
486  callsign = w1.left(w2.length() == 1 ? 4:3);
487  callsign += w2.left(5 - callsign.length());
488  }
489  (*i).m_callSign = callsign;
490  }
491 
492  if (chanid > 0)
493  {
494  QString cstr = (*i).m_chanNum;
495  if(m_channelPreset && cstr.isEmpty())
496  cstr = QString::number(chanid % 1000);
497 
498  bool retval = ChannelUtil::CreateChannel(
499  mplexid, id,
500  chanid,
501  (*i).m_callSign,
502  (*i).m_name, cstr,
503  0 /*service id*/,
504  major, minor,
505  false /*use on air guide*/,
507  (*i).m_freqId,
508  localfile,
509  (*i).m_tvFormat,
510  (*i).m_xmltvId
511  );
512  if (!retval)
513  std::cout << "Channel " << chanid << " creation failed"
514  << std::endl;
515  }
516  }
517  }
518  }
519 }
ChannelInfo
Definition: channelinfo.h:31
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:216
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:811
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
ChannelData::normalizeChannelKey
static QString normalizeChannelKey(const QString &chanName)
Definition: channeldata.cpp:121
mythdb.h
SourceUtil::IsCableCardPresent
static bool IsCableCardPresent(uint sourceid)
Definition: sourceutil.cpp:351
ChannelInfo::m_chanId
uint m_chanId
Definition: channelinfo.h:85
ChannelUtil::LoadChannels
static ChannelInfoList LoadChannels(uint startIndex, uint count, uint &totalAvailable, bool ignoreHidden=true, OrderBy orderBy=kChanOrderByChanNum, GroupBy groupBy=kChanGroupByChanid, uint sourceID=0, uint channelGroupID=0, bool liveTVOnly=false, const QString &callsign="", const QString &channum="", bool ignoreUntunable=true)
Load channels from database into a list of ChannelInfo objects.
Definition: channelutil.cpp:2452
ChannelData::handleChannels
void handleChannels(int id, ChannelInfoList *chanlist) const
Definition: channeldata.cpp:191
ChannelData::m_cardType
QString m_cardType
Definition: channeldata.h:33
ChannelInfo::m_freqId
QString m_freqId
Definition: channelinfo.h:87
freq
static const std::array< const uint32_t, 4 > freq
Definition: element.cpp:45
ChannelInfo::m_fineTune
int m_fineTune
Definition: channelinfo.h:95
ChannelUtil::kChanGroupByChanid
@ kChanGroupByChanid
Definition: channelutil.h:217
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:205
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:617
ChannelInfo::m_name
QString m_name
Definition: channelinfo.h:92
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
ChannelData::promptForChannelUpdates
unsigned int promptForChannelUpdates(ChannelInfoList::iterator chaninfo, unsigned int chanid) const
Definition: channeldata.cpp:85
ChannelInfo::m_icon
QString m_icon
Definition: channelinfo.h:93
ChannelData::m_channelPreset
bool m_channelPreset
Definition: channeldata.h:30
ChannelData::channelList
static ChannelList channelList(int sourceId)
Definition: channeldata.cpp:133
sourceutil.h
ChannelData::m_guideDataOnly
bool m_guideDataOnly
Definition: channeldata.h:29
ChannelData::m_interactive
bool m_interactive
Definition: channeldata.h:28
minor
#define minor(X)
Definition: compat.h:78
mythlogging.h
CardUtil::IsEncoder
static bool IsEncoder(const QString &rawtype)
Definition: cardutil.h:135
ChannelData::m_channelUpdates
bool m_channelUpdates
Definition: channeldata.h:31
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:549
SetupIconCacheDirectory
QString SetupIconCacheDirectory(void)
Definition: fillutil.cpp:35
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
ChannelInfo::m_chanNum
QString m_chanNum
Definition: channelinfo.h:86
getResponse
QString getResponse(const QString &query, const QString &def)
In an interactive shell, prompt the user to input a string.
Definition: mythmiscutil.cpp:410
ChannelUtil::CreateChanID
static int CreateChanID(uint sourceid, const QString &chan_num)
Creates a unique channel ID for database use.
Definition: channelutil.cpp:1446
SourceUtil::IsUnscanable
static bool IsUnscanable(uint sourceid)
Definition: sourceutil.cpp:342
uint
unsigned int uint
Definition: compat.h:81
get_atsc_stuff
static void get_atsc_stuff(const QString &channum, int sourceid, int freqid, int &major, int &minor, long long &freq)
Definition: channeldata.cpp:30
MSqlQuery::ChannelCon
static MSqlQueryInfo ChannelCon()
Returns dedicated connection. (Required for using temporary SQL tables.)
Definition: mythdbcon.cpp:598
ChannelUtil::CreateChannel
static bool CreateChannel(uint db_mplexid, uint db_sourceid, uint new_channel_id, const QString &callsign, const QString &service_name, const QString &chan_num, uint service_id, uint atsc_major_channel, uint atsc_minor_channel, bool use_on_air_guide, ChannelVisibleType visible, const QString &freqid, const QString &icon=QString(), QString format="Default", const QString &xmltvid=QString(), const QString &default_authority=QString(), uint service_type=0, int recpriority=0, int tmOffset=0, int commMethod=-1)
Definition: channelutil.cpp:1483
channelutil.h
mythmiscutil.h
frequencytables.h
kChannelVisible
@ kChannelVisible
Definition: channelinfo.h:23
cardutil.h
ChannelUtil::CreateMultiplex
static uint CreateMultiplex(int sourceid, const QString &sistandard, uint64_t frequency, const QString &modulation, int transport_id=-1, int network_id=-1)
Definition: channelutil.cpp:370
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:887
channeldata.h
ChannelInfo::m_tvFormat
QString m_tvFormat
Definition: channelinfo.h:105
ChannelData::FindMatchingChannel
static ChannelInfo FindMatchingChannel(const ChannelInfo &chanInfo, ChannelList existingChannels)
Definition: channeldata.cpp:155
get_center_frequency
long long get_center_frequency(const QString &format, const QString &modulation, const QString &country, int freqid)
Definition: frequencytables.cpp:262
SourceUtil::IsEncoder
static bool IsEncoder(uint sourceid, bool strict=false)
Definition: sourceutil.cpp:308
ChannelInfo::m_xmltvId
QString m_xmltvId
Definition: channelinfo.h:97
ChannelList
QList< ChannelListItem > ChannelList
Definition: channelscan_sm.h:68
ChannelData::insert_chan
bool insert_chan(uint sourceid) const
Definition: channeldata.cpp:60
parseMajorMinor
static const QRegularExpression parseMajorMinor
Definition: channeldata.cpp:28
mythdownloadmanager.h
CardUtil::IsUnscanable
static bool IsUnscanable(const QString &rawtype)
Definition: cardutil.h:158
build_compdb.filename
filename
Definition: build_compdb.py:21
fillutil.h
ChannelInfo::m_callSign
QString m_callSign
Definition: channelinfo.h:91
ChannelUtil::kChanOrderByChanNum
@ kChanOrderByChanNum
Definition: channelutil.h:208
GetMythDownloadManager
MythDownloadManager * GetMythDownloadManager(void)
Gets the pointer to the MythDownloadManager singleton.
Definition: mythdownloadmanager.cpp:145
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:836
ChannelInfoList
std::vector< ChannelInfo > ChannelInfoList
Definition: channelinfo.h:131