MythTV  master
channelinfo.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 
3 // Qt headers
4 #include <QFile>
5 #include <QDir>
6 #include <QFileInfo>
7 #include <QImage>
8 #include <QUrl>
9 
10 // MythTV headers
11 #include "channelinfo.h"
12 #include "mythcorecontext.h"
13 #include "mythdb.h"
14 #include "mythdirs.h"
15 #include "mpegstreamdata.h" // for CryptStatus
16 #include "remotefile.h"
17 #include "channelgroup.h"
18 #include "sourceutil.h"
19 
22 
24 {
25  // Channel table
26  m_chanid = other.m_chanid;
27  m_channum = other.m_channum;
28  m_freqid = other.m_freqid;
29  m_sourceid = other.m_sourceid;
30  m_callsign = other.m_callsign;
31  m_name = other.m_name;
32  m_icon = other.m_icon;
33  m_finetune = other.m_finetune;
35  m_xmltvid = other.m_xmltvid;
37  m_contrast = other.m_contrast;
38  m_brightness = other.m_brightness;
39  m_colour = other.m_colour;
40  m_hue = other.m_hue;
41  m_tvformat = other.m_tvformat;
42  m_visible = other.m_visible;
45  m_mplexid = (other.m_mplexid == 32767) ? 0 : other.m_mplexid;
46  m_serviceid = other.m_serviceid;
51  m_commmethod = other.m_commmethod;
52  m_tmoffset = other.m_tmoffset;
53  m_iptvid = other.m_iptvid;
54 
55  // Not in channel table
59  m_sourcename = other.m_sourcename;
60 }
61 
63  const QString &_channum, const QString &_callsign,
64  uint _chanid, uint _major_chan, uint _minor_chan,
65  uint _mplexid, bool _visible,
66  const QString &_name, const QString &_icon,
67  uint _sourceid)
68 {
69  m_channum = _channum;
70  m_callsign = _callsign;
71  m_name = _name;
72  m_icon = _icon;
73  m_chanid = _chanid;
74  m_atsc_major_chan = _major_chan;
75  m_atsc_minor_chan = _minor_chan;
76  m_mplexid = (_mplexid == 32767) ? 0 : _mplexid;
77  m_sourceid = _sourceid;
78  m_visible = _visible;
79 }
80 
82 {
83  if (this == &other)
84  return *this;
85 
86  // Channel table
87  m_chanid = other.m_chanid;
88  m_channum = other.m_channum;
89  m_freqid = other.m_freqid;
90  m_sourceid = other.m_sourceid;
91  m_callsign = other.m_callsign;
92  m_name = other.m_name;
93  m_icon = other.m_icon;
94  m_finetune = other.m_finetune;
96  m_xmltvid = other.m_xmltvid;
98  m_contrast = other.m_contrast;
99  m_brightness = other.m_brightness;
100  m_colour = other.m_colour;
101  m_hue = other.m_hue;
102  m_tvformat = other.m_tvformat;
103  m_visible = other.m_visible;
106  m_mplexid = (other.m_mplexid == 32767) ? 0 : other.m_mplexid;
107  m_serviceid = other.m_serviceid;
112  m_commmethod = other.m_commmethod;
113  m_tmoffset = other.m_tmoffset;
114  m_iptvid = other.m_iptvid;
115 
116  // Not in channel table
120  m_sourcename = other.m_sourcename;
121 
122  return *this;
123 }
124 
125 bool ChannelInfo::Load(uint lchanid)
126 {
127  if (lchanid == 0 && m_chanid == 0)
128  return false;
129 
130  if (lchanid == 0)
131  lchanid = m_chanid;
132 
133  MSqlQuery query(MSqlQuery::InitCon());
134  query.prepare("SELECT channum, freqid, sourceid, "
135  "callsign, name, icon, finetune, videofilters, xmltvid, "
136  "recpriority, contrast, brightness, colour, hue, tvformat, "
137  "visible, outputfilters, useonairguide, mplexid, "
138  "serviceid, atsc_major_chan, atsc_minor_chan, last_record, "
139  "default_authority, commmethod, tmoffset, iptvid "
140  "FROM channel WHERE chanid = :CHANID ;");
141 
142  query.bindValue(":CHANID", lchanid);
143 
144  if (!query.exec())
145  {
146  MythDB::DBError("ChannelInfo::Load()", query);
147  return false;
148  }
149 
150  if (!query.next())
151  return false;
152 
153  m_chanid = lchanid;
154  m_channum = query.value(0).toString();
155  m_freqid = query.value(1).toString();
156  m_sourceid = query.value(2).toUInt();
157  m_callsign = query.value(3).toString();
158  m_name = query.value(4).toString();
159  m_icon = query.value(5).toString();
160  m_finetune = query.value(6).toInt();
161  m_videofilters = query.value(7).toString();
162  m_xmltvid = query.value(8).toString();
163  m_recpriority = query.value(9).toInt();
164  m_contrast = query.value(10).toUInt();
165  m_brightness = query.value(11).toUInt();
166  m_colour = query.value(12).toUInt();
167  m_hue = query.value(13).toUInt();
168  m_tvformat = query.value(14).toString();
169  m_visible = query.value(15).toBool();
170  m_outputfilters = query.value(16).toString();
171  m_useonairguide = query.value(17).toBool();
172  m_mplexid = query.value(18).toUInt();
173  m_serviceid = query.value(19).toUInt();
174  m_atsc_major_chan = query.value(20).toUInt();
175  m_atsc_minor_chan = query.value(21).toUInt();
176  m_last_record = query.value(22).toDateTime();
177  m_default_authority = query.value(23).toString();
178  m_commmethod = query.value(24).toUInt();
179  m_tmoffset = query.value(25).toUInt();
180  m_iptvid = query.value(26).toUInt();
181 
182  return true;
183 }
184 
185 QString ChannelInfo::GetFormatted(const ChannelFormat &format) const
186 {
187  QString tmp;
188 
189  if (format & kChannelLong)
190  tmp = gCoreContext->GetSetting("LongChannelFormat", "<num> <name>");
191  else // kChannelShort
192  tmp = gCoreContext->GetSetting("ChannelFormat", "<num> <sign>");
193 
194 
195  if (tmp.isEmpty())
196  return QString();
197 
198  tmp.replace("<num>", m_channum);
199  tmp.replace("<sign>", m_callsign);
200  tmp.replace("<name>", m_name);
201 
202  return tmp;
203 }
204 
206 {
207  if (m_sourceid > 0 && m_sourcename.isNull())
209 
210  return m_sourcename;
211 }
212 
214 {
215  infoMap["callsign"] = m_callsign;
216  infoMap["channeliconpath"] = m_icon;
217  //infoMap["chanstr"] = chanstr;
218  infoMap["channelname"] = m_name;
219  infoMap["channelid"] = QString().setNum(m_chanid);
220  infoMap["channelsourcename"] = GetSourceName();
221  infoMap["channelrecpriority"] = QString().setNum(m_recpriority);
222 
223  infoMap["channelnumber"] = m_channum;
224 
225  infoMap["majorchan"] = QString().setNum(m_atsc_major_chan);
226  infoMap["minorchan"] = QString().setNum(m_atsc_minor_chan);
227  infoMap["mplexid"] = QString().setNum(m_mplexid);
228  infoMap["channelvisible"] = m_visible ? QObject::tr("Yes") : QObject::tr("No");
229 
230  if (!GetGroupIds().isEmpty())
231  infoMap["channelgroupname"] = ChannelGroup::GetChannelGroupName(GetGroupIds().first());
232 }
233 
235 {
236  if (m_chanid && m_inputIdList.isEmpty())
237  {
238  MSqlQuery query(MSqlQuery::InitCon());
239  query.prepare("SELECT capturecard.cardid FROM channel "
240  "JOIN capturecard ON capturecard.sourceid = channel.sourceid "
241  "WHERE chanid = :CHANID");
242  query.bindValue(":CHANID", m_chanid);
243 
244  if (!query.exec())
245  MythDB::DBError("ChannelInfo::GetInputIds()", query);
246  else
247  {
248  while(query.next())
249  {
250  AddInputId(query.value(0).toUInt());
251  }
252  }
253  }
254 }
255 
257 {
258  if (m_chanid && m_groupIdList.isEmpty())
259  {
260  MSqlQuery query(MSqlQuery::InitCon());
261  query.prepare("SELECT grpid FROM channelgroup "
262  "WHERE chanid = :CHANID");
263  query.bindValue(":CHANID", m_chanid);
264 
265  if (!query.exec())
266  MythDB::DBError("ChannelInfo::GetInputIds()", query);
267  else if (query.size() == 0)
268  {
269  // HACK Avoid re-running this query each time for channels
270  // which don't belong to any group
271  AddGroupId(0);
272  }
273  else
274  {
275  while(query.next())
276  {
277  AddGroupId(query.value(0).toUInt());
278  }
279  }
280  }
281 }
282 
285 
286 bool ChannelInsertInfo::SaveScan(uint scanid, uint transportid) const
287 {
288  MSqlQuery query(MSqlQuery::InitCon());
289  query.prepare(
290  "INSERT INTO channelscan_channel "
291  " ( scanid, transportid, "
292  " mplex_id, source_id, channel_id, "
293  " callsign, service_name, chan_num, "
294  " service_id, atsc_major_channel, atsc_minor_channel, "
295  " use_on_air_guide, hidden, hidden_in_guide, "
296  " freqid, icon, tvformat, "
297  " xmltvid, pat_tsid, vct_tsid, "
298  " vct_chan_tsid, sdt_tsid, orig_netid, "
299  " netid, si_standard, in_channels_conf, "
300  " in_pat, in_pmt, in_vct, "
301  " in_nit, in_sdt, is_encrypted, "
302  " is_data_service, is_audio_service, is_opencable, "
303  " could_be_opencable, decryption_status, default_authority "
304  " ) "
305  "VALUES "
306  " ( :SCANID, :TRANSPORTID, "
307  " :MPLEX_ID, :SOURCE_ID, :CHANNEL_ID, "
308  " :CALLSIGN, :SERVICE_NAME, :CHAN_NUM, "
309  " :SERVICE_ID, :ATSC_MAJOR_CHANNEL,:ATSC_MINOR_CHANNEL, "
310  " :USE_ON_AIR_GUIDE, :HIDDEN, :HIDDEN_IN_GUIDE, "
311  " :FREQID, :ICON, :TVFORMAT, "
312  " :XMLTVID, :PAT_TSID, :VCT_TSID, "
313  " :VCT_CHAN_TSID, :SDT_TSID, :ORIG_NETID, "
314  " :NETID, :SI_STANDARD, :IN_CHANNELS_CONF, "
315  " :IN_PAT, :IN_PMT, :IN_VCT, "
316  " :IN_NIT, :IN_SDT, :IS_ENCRYPTED, "
317  " :IS_DATA_SERVICE, :IS_AUDIO_SERVICE, :IS_OPENCABLE, "
318  " :COULD_BE_OPENCABLE,:DECRYPTION_STATUS, :DEFAULT_AUTHORITY "
319  " );");
320 
321  query.bindValue(":SCANID", scanid);
322  query.bindValue(":TRANSPORTID", transportid);
323  query.bindValue(":MPLEX_ID", m_db_mplexid);
324  query.bindValue(":SOURCE_ID", m_source_id);
325  query.bindValue(":CHANNEL_ID", m_channel_id);
326  query.bindValueNoNull(":CALLSIGN", m_callsign);
327  query.bindValueNoNull(":SERVICE_NAME", m_service_name);
328  query.bindValueNoNull(":CHAN_NUM", m_chan_num);
329  query.bindValue(":SERVICE_ID", m_service_id);
330  query.bindValue(":ATSC_MAJOR_CHANNEL", m_atsc_major_channel);
331  query.bindValue(":ATSC_MINOR_CHANNEL", m_atsc_minor_channel);
332  query.bindValue(":USE_ON_AIR_GUIDE", m_use_on_air_guide);
333  query.bindValue(":HIDDEN", m_hidden);
334  query.bindValue(":HIDDEN_IN_GUIDE", m_hidden_in_guide);
335  query.bindValueNoNull(":FREQID", m_freqid);
336  query.bindValueNoNull(":ICON", m_icon);
337  query.bindValueNoNull(":TVFORMAT", m_format);
338  query.bindValueNoNull(":XMLTVID", m_xmltvid);
339  query.bindValue(":PAT_TSID", m_pat_tsid);
340  query.bindValue(":VCT_TSID", m_vct_tsid);
341  query.bindValue(":VCT_CHAN_TSID", m_vct_chan_tsid);
342  query.bindValue(":SDT_TSID", m_sdt_tsid);
343  query.bindValue(":ORIG_NETID", m_orig_netid);
344  query.bindValue(":NETID", m_netid);
345  query.bindValueNoNull(":SI_STANDARD", m_si_standard);
346  query.bindValue(":IN_CHANNELS_CONF", m_in_channels_conf);
347  query.bindValue(":IN_PAT", m_in_pat);
348  query.bindValue(":IN_PMT", m_in_pmt);
349  query.bindValue(":IN_VCT", m_in_vct);
350  query.bindValue(":IN_NIT", m_in_nit);
351  query.bindValue(":IN_SDT", m_in_sdt);
352  query.bindValue(":IS_ENCRYPTED", m_is_encrypted);
353  query.bindValue(":IS_DATA_SERVICE", m_is_data_service);
354  query.bindValue(":IS_AUDIO_SERVICE", m_is_audio_service);
355  query.bindValue(":IS_OPENCABLE", m_is_opencable);
356  query.bindValue(":COULD_BE_OPENCABLE", m_could_be_opencable);
357  query.bindValue(":DECRYPTION_STATUS", m_decryption_status);
358  query.bindValueNoNull(":DEFAULT_AUTHORITY", m_default_authority);
359 
360  if (!query.exec())
361  {
362  MythDB::DBError("ChannelInsertInfo SaveScan 1", query);
363  return false;
364  }
365 
366  return true;
367 }
368 
370 {
371  if (other.m_db_mplexid && !m_db_mplexid)
372  m_db_mplexid = other.m_db_mplexid;
373  if (other.m_source_id && !m_source_id)
374  m_source_id = other.m_source_id;
375  if (other.m_channel_id && !m_channel_id)
376  m_channel_id = other.m_channel_id;
377  if (!other.m_callsign.isEmpty() && m_callsign.isEmpty())
378  m_callsign = other.m_callsign;
379  if (!other.m_service_name.isEmpty() && m_service_name.isEmpty())
381  if (!other.m_chan_num.isEmpty() &&
382  ((m_chan_num.isEmpty() || m_chan_num == "0")))
383  m_chan_num = other.m_chan_num;
384  if (other.m_service_id && !m_service_id)
385  m_service_id = other.m_service_id;
390  //m_use_on_air_guide = other.m_use_on_air_guide;
391  //m_hidden = other.m_hidden;
392  //m_hidden_in_guide = other.m_hidden_in_guide;
393  if (!other.m_freqid.isEmpty() && m_freqid.isEmpty())
394  m_freqid = other.m_freqid;
395  if (!other.m_icon.isEmpty() && m_icon.isEmpty())
396  m_icon = other.m_icon;
397  if (!other.m_format.isEmpty() && m_format.isEmpty())
398  m_format = other.m_format;
399  if (!other.m_xmltvid.isEmpty() && m_xmltvid.isEmpty())
400  m_xmltvid = other.m_xmltvid;
401  if (!other.m_default_authority.isEmpty() && m_default_authority.isEmpty())
403  // non-DB info
404  if (other.m_pat_tsid && !m_pat_tsid)
405  m_pat_tsid = other.m_pat_tsid;
406  if (other.m_vct_tsid && !m_vct_tsid)
407  m_vct_tsid = other.m_vct_tsid;
408  if (other.m_vct_chan_tsid && !m_vct_chan_tsid)
410  if (other.m_sdt_tsid && !m_sdt_tsid)
411  m_sdt_tsid = other.m_sdt_tsid;
412  if (other.m_orig_netid && !m_orig_netid)
413  m_orig_netid = other.m_orig_netid;
414  if (other.m_netid && !m_netid)
415  m_netid = other.m_netid;
416  if (!other.m_si_standard.isEmpty() &&
417  (m_si_standard.isEmpty() || ("mpeg" == m_si_standard)))
421  if (other.m_in_pat && !m_in_pat)
422  m_in_pat = other.m_in_pat;
423  if (other.m_in_pmt && !m_in_pmt)
424  m_in_pmt = other.m_in_pmt;
425  if (other.m_in_vct && !m_in_vct)
426  m_in_vct = other.m_in_vct;
427  if (other.m_in_nit && !m_in_nit)
428  m_in_nit = other.m_in_nit;
429  if (other.m_in_sdt && !m_in_sdt)
430  m_in_sdt = other.m_in_sdt;
431  if (other.m_in_pat && !m_in_pat)
433  if (other.m_is_data_service && !m_is_data_service)
437  if (other.m_is_opencable && !m_is_opencable)
443 }
444 
446  const ChannelInsertInfo &other, bool relaxed) const
447 {
448  if (m_atsc_major_channel &&
451  {
452  return true;
453  }
454 
455  if ((m_orig_netid == other.m_orig_netid) &&
456  (m_sdt_tsid == other.m_sdt_tsid) &&
457  (m_service_id == other.m_service_id))
458  return true;
459 
460  if (!m_orig_netid && !other.m_orig_netid &&
461  (m_pat_tsid == other.m_pat_tsid) && (m_service_id == other.m_service_id))
462  return true;
463 
464  if (relaxed)
465  {
466  if (("mpeg" == m_si_standard || "mpeg" == other.m_si_standard ||
467  "dvb" == m_si_standard || "dvb" == other.m_si_standard ||
468  m_si_standard.isEmpty() || other.m_si_standard.isEmpty()) &&
469  (m_service_id == other.m_service_id))
470  {
471  return true;
472  }
473  }
474 
475  return false;
476 }
477 
478 /* vim: set expandtab tabstop=4 shiftwidth=4: */
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:782
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:863
void ToMap(InfoMap &infoMap)
QString m_name
Definition: channelinfo.h:82
QString m_service_name
Definition: channelinfo.h:205
int m_recpriority
Definition: channelinfo.h:88
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
QString GetFormatted(const ChannelFormat &format) const
void ImportExtraInfo(const ChannelInsertInfo &other)
QString m_videofilters
Definition: channelinfo.h:86
QString m_outputfilters
Definition: channelinfo.h:97
ChannelInfo & operator=(const ChannelInfo &)
Definition: channelinfo.cpp:81
int size(void) const
Definition: mythdbcon.h:203
void AddInputId(uint linputid)
Definition: channelinfo.h:61
unsigned int uint
Definition: compat.h:140
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
bool SaveScan(uint scanid, uint transportid) const
QString m_xmltvid
Definition: channelinfo.h:87
void LoadInputIds()
static guint32 * tmp
Definition: goom_core.c:35
ChannelInfo()=default
QString GetSourceName()
QString m_tvformat
Definition: channelinfo.h:95
QString m_icon
Definition: channelinfo.h:83
static QString GetSourceName(uint sourceid)
Definition: sourceutil.cpp:44
QVariant value(int i) const
Definition: mythdbcon.h:198
QString m_sourcename
Definition: channelinfo.h:115
uint m_serviceid
Definition: channelinfo.h:101
void AddGroupId(uint lgroupid)
Definition: channelinfo.h:49
uint m_atsc_major_chan
Definition: channelinfo.h:102
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
QString GetSetting(const QString &key, const QString &defaultval="")
QString m_freqid
Definition: channelinfo.h:77
uint m_sourceid
Definition: channelinfo.h:79
int m_finetune
Definition: channelinfo.h:85
uint m_mplexid
Definition: channelinfo.h:100
int m_commmethod
Definition: channelinfo.h:108
QList< uint > m_inputIdList
Definition: channelinfo.h:118
void LoadGroupIds()
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
static QString GetChannelGroupName(int grpid)
const QList< uint > GetGroupIds() const
Definition: channelinfo.h:47
QDateTime m_last_record
Definition: channelinfo.h:105
QString m_channum
Definition: channelinfo.h:76
uint m_contrast
Definition: channelinfo.h:90
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:807
bool Load(uint lchanid=-1)
QString m_si_standard
Definition: channelinfo.h:226
QString m_old_xmltvid
Definition: channelinfo.h:112
bool IsSameChannel(const ChannelInsertInfo &, bool relaxed=false) const
uint m_atsc_minor_chan
Definition: channelinfo.h:103
void bindValueNoNull(const QString &placeholder, const QVariant &val)
Add a single binding, taking care not to set a NULL value.
Definition: mythdbcon.cpp:868
bool m_visible
Definition: channelinfo.h:96
QString m_callsign
Definition: channelinfo.h:81
QString m_default_authority
Definition: channelinfo.h:217
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
bool m_useonairguide
Definition: channelinfo.h:98
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:179
uint m_colour
Definition: channelinfo.h:92
QString m_default_authority
Definition: channelinfo.h:107
QList< uint > m_groupIdList
Definition: channelinfo.h:117
uint m_chanid
Definition: channelinfo.h:75
uint m_brightness
Definition: channelinfo.h:91