MythTV  0.27pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
channelsettings.cpp
Go to the documentation of this file.
1 #include <QWidget>
2 #include <QFile>
3 
4 #include "channelsettings.h"
5 #include "channelutil.h"
6 #include "programinfo.h" // for COMM_DETECT*, GetPreferredSkipTypeCombinations()
7 #include "mpegtables.h"
8 #include "mythdirs.h"
9 #include "cardutil.h"
10 
12 {
13  QString fieldTag = (":WHERE" + id.getField().toUpper());
14  QString query(id.getField() + " = " + fieldTag);
15 
16  bindings.insert(fieldTag, id.getValue());
17 
18  return query;
19 }
20 
22 {
23  QString fieldTag = (":SET" + id.getField().toUpper());
24  QString nameTag = (":SET" + GetColumnName().toUpper());
25 
26  QString query(id.getField() + " = " + fieldTag + ", " +
27  GetColumnName() + " = " + nameTag);
28 
29  bindings.insert(fieldTag, id.getValue());
30  bindings.insert(nameTag, user->GetDBValue());
31 
32  return query;
33 }
34 
35 /*****************************************************************************
36  Channel Options - Common
37  *****************************************************************************/
38 
39 class Name : public LineEditSetting, public ChannelDBStorage
40 {
41  public:
42  Name(const ChannelID &id) :
43  LineEditSetting(this), ChannelDBStorage(this, id, "name")
44  {
45  setLabel(QObject::tr("Channel Name"));
46  }
47 };
48 
50 {
51  public:
52  Channum(const ChannelID &id) :
53  LineEditSetting(this), ChannelDBStorage(this, id, "channum")
54  {
55  setLabel(QObject::tr("Channel Number"));
56  }
57 };
58 
59 class Source : public ComboBoxSetting, public ChannelDBStorage
60 {
61  public:
62  Source(const ChannelID &id, uint _default_sourceid) :
63  ComboBoxSetting(this), ChannelDBStorage(this, id, "sourceid"),
64  default_sourceid(_default_sourceid)
65  {
66  setLabel(QObject::tr("Video Source"));
67  }
68 
69  void Load(void)
70  {
73 
74  if (default_sourceid && !getValue().toUInt())
75  {
77  if (which)
78  setValue(which);
79  }
80  }
81 
82  void fillSelections(void)
83  {
84  addSelection(QObject::tr("[Not Selected]"), "0");
85 
87  query.prepare("SELECT name, sourceid "
88  "FROM videosource "
89  "ORDER BY sourceid");
90 
91  if (!query.exec() || !query.isActive())
92  {
93  MythDB::DBError("Source::fillSelections", query);
94  }
95  else
96  {
97  for (uint i = 1; query.next(); i++)
98  {
99  sourceid_to_index[query.value(1).toUInt()] = i;
100  addSelection(query.value(0).toString(),
101  query.value(1).toString());
102  }
103  }
104 
105  sourceid_to_index[0] = 0; // Not selected entry.
106  }
107 
108  private:
110  QMap<uint,uint> sourceid_to_index;
111 };
112 
114 {
115  public:
116  Callsign(const ChannelID &id) :
117  LineEditSetting(this), ChannelDBStorage(this, id, "callsign")
118  {
119  setLabel(QObject::tr("Callsign"));
120  }
121 };
122 
124  ComboBoxSetting(this), ChannelDBStorage(this, id, "tvformat")
125 {
126  setLabel(QObject::tr("TV Format"));
127  setHelpText(
128  QObject::tr(
129  "If this channel uses a format other than TV "
130  "Format in the General Backend Setup screen, set it here."));
131 
132  addSelection(QObject::tr("Default"), "Default");
133 
134  QStringList list = GetFormats();
135  for (int i = 0; i < list.size(); i++)
136  addSelection(list[i]);
137 }
138 
140 {
141  QStringList list;
142 
143  list.push_back("NTSC");
144  list.push_back("NTSC-JP");
145  list.push_back("PAL");
146  list.push_back("PAL-60");
147  list.push_back("PAL-BG");
148  list.push_back("PAL-DK");
149  list.push_back("PAL-D");
150  list.push_back("PAL-I");
151  list.push_back("PAL-M");
152  list.push_back("PAL-N");
153  list.push_back("PAL-NC");
154  list.push_back("SECAM");
155  list.push_back("SECAM-D");
156  list.push_back("SECAM-DK");
157 
158  return list;
159 }
160 
162 {
163  public:
164  TimeOffset(const ChannelID &id) :
165  SpinBoxSetting(this, -1440, 1440, 1),
166  ChannelDBStorage(this, id, "tmoffset")
167  {
168  setLabel(QObject::tr("DataDirect") + " " + QObject::tr("Time Offset"));
169  setHelpText(QObject::tr("Offset (in minutes) to apply to the program "
170  "guide data during import. This can be used when the "
171  "listings for a particular channel are in a different "
172  "time zone.") + " " +
173  QObject::tr("(Works for DataDirect listings only.)"));
174  }
175 };
176 
178 {
179  public:
180  Priority(const ChannelID &id) :
181  SpinBoxSetting(this, -99, 99, 1),
182  ChannelDBStorage(this, id, "recpriority")
183  {
184  setLabel(QObject::tr("Priority"));
185  setHelpText(
186  QObject::tr("Number of priority points to be added to any "
187  "recording on this channel during scheduling.")+" "+
188  QObject::tr("Use a positive number as the priority if you "
189  "want this to be a preferred channel, a "
190  "negative one to deprecate this channel."));
191  }
192 };
193 
194 class Icon : public LineEditSetting, public ChannelDBStorage
195 {
196  public:
197  Icon(const ChannelID &id) :
198  LineEditSetting(this), ChannelDBStorage(this, id, "icon")
199  {
200  setLabel(QObject::tr("Icon"));
201  setHelpText(QObject::tr("Image file to use as the icon for this "
202  "channel on various MythTV displays."));
203  }
204 };
205 
207 {
208  public:
209  VideoFilters(const ChannelID &id) :
210  LineEditSetting(this), ChannelDBStorage(this, id, "videofilters")
211  {
212  setLabel(QObject::tr("Video filters"));
213  setHelpText(QObject::tr("Filters to be used when recording "
214  "from this channel. Not used with "
215  "hardware encoding cards."));
216 
217  }
218 };
219 
220 
222 {
223  public:
225  LineEditSetting(this), ChannelDBStorage(this, id, "outputfilters")
226  {
227  setLabel(QObject::tr("Playback filters"));
228  setHelpText(QObject::tr("Filters to be used when recordings "
229  "from this channel are viewed. "
230  "Start with a plus to append to the "
231  "global playback filters."));
232  }
233 };
234 
236 {
237  public:
238  XmltvID(const ChannelID &id, const QString &_sourceName) :
239  ComboBoxSetting(this, true), ChannelDBStorage(this, id, "xmltvid"),
240  sourceName(_sourceName)
241  {
242  setLabel(QObject::tr("XMLTV ID"));
243  setHelpText(QObject::tr(
244  "ID used by listing services to get an exact "
245  "correspondance between a channel in your line-up "
246  "and a channel in their database. Normally this is "
247  "set automatically when 'mythfilldatabase' is run."));
248  }
249 
250  void Load(void)
251  {
252  fillSelections();
254  }
255 
256  void fillSelections(void)
257  {
258  clearSelections();
259 
260  QString xmltvFile = GetConfDir() + '/' + sourceName + ".xmltv";
261 
262  if (QFile::exists(xmltvFile))
263  {
264  QFile file(xmltvFile);
265  if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
266  return;
267 
268  QStringList idList;
269 
270  while (!file.atEnd())
271  {
272  QByteArray line = file.readLine();
273 
274  if (line.startsWith("channel="))
275  {
276  QString id = line.mid(8, -1).trimmed();
277  idList.append(id);
278  }
279  }
280 
281  idList.sort();
282 
283  for (int x = 0; x < idList.size(); x++)
284  addSelection(idList.at(x), idList.at(x));
285  }
286  }
287 
288  private:
289  QString sourceName;
290 };
291 
293 {
294  public:
295  CommMethod(const ChannelID &id) :
296  ComboBoxSetting(this), ChannelDBStorage(this, id, "commmethod")
297  {
298  setLabel(QObject::tr("Commercial Detection Method"));
299  setHelpText(QObject::tr("Changes the method of "
300  "commercial detection used for recordings on this channel or "
301  "skips detection by marking the channel as Commercial Free."));
302 
304  tmp.push_front(COMM_DETECT_UNINIT);
305  tmp.push_back(COMM_DETECT_COMMFREE);
306 
307  for (uint i = 0; i < tmp.size(); i++)
308  addSelection(SkipTypeToString(tmp[i]), QString::number(tmp[i]));
309  }
310 };
311 
313 {
314  public:
315  Visible(const ChannelID &id) :
316  CheckBoxSetting(this), ChannelDBStorage(this, id, "visible")
317  {
318  setValue(true);
319  setLabel(QObject::tr("Visible"));
320  setHelpText(QObject::tr("If enabled, the channel will be visible in the "
321  "EPG."));
322  }
323 };
324 
326 {
327  public:
328  OnAirGuide(const ChannelID &id) :
329  CheckBoxSetting(this), ChannelDBStorage(this, id, "useonairguide")
330  {
331  setLabel(QObject::tr("Use on air guide"));
332  setHelpText(QObject::tr("If enabled, guide information for this "
333  "channel will be updated using 'Over-the-Air' "
334  "program listings."));
335  }
336 };
337 
338 /*****************************************************************************
339  Channel Options - Video 4 Linux
340  *****************************************************************************/
341 
343 {
344  public:
345  Freqid(const ChannelID &id) :
346  LineEditSetting(this), ChannelDBStorage(this, id, "freqid")
347  {
348  setLabel(QObject::tr("Frequency")+" "+QObject::tr("or")+" "+
349  QObject::tr("Channel"));
350  setHelpText(QObject::tr(
351  "Specify either the exact frequency (in kHz) or "
352  "a valid channel for your 'TV Format'."));
353  }
354 };
355 
357 {
358  public:
359  Finetune(const ChannelID& id)
360  : SliderSetting(this, -300, 300, 1),
361  ChannelDBStorage(this, id, "finetune")
362  {
363  setLabel(QObject::tr("Finetune")+" (kHz)");
364  setHelpText(QObject::tr("Value to be added to your desired frequency "
365  "(in kHz) for 'fine tuning'."));
366  }
367 };
368 
370 {
371  public:
372  Contrast(const ChannelID &id) :
373  SliderSetting(this, 0, 65535, 655),
374  ChannelDBStorage(this, id, "contrast")
375  {
376  setLabel(QObject::tr("Contrast"));
377  }
378 };
379 
381 {
382  public:
383  Brightness(const ChannelID &id) :
384  SliderSetting(this, 0, 65535, 655),
385  ChannelDBStorage(this, id, "brightness")
386  {
387  setLabel(QObject::tr("Brightness"));
388  }
389 };
390 
391 class Colour : public SliderSetting, public ChannelDBStorage
392 {
393  public:
394  Colour(const ChannelID &id) :
395  SliderSetting(this, 0, 65535, 655),
396  ChannelDBStorage(this, id, "colour")
397  {
398  setLabel(QObject::tr("Color"));
399  }
400 };
401 
402 class Hue : public SliderSetting, public ChannelDBStorage
403 {
404  public:
405  Hue(const ChannelID &id) :
406  SliderSetting(this, 0, 65535, 655), ChannelDBStorage(this, id, "hue")
407  {
408  setLabel(QObject::tr("Hue"));
409  }
410 };
411 
413  uint default_sourceid) :
415 {
416  setLabel(QObject::tr("Channel Options - Common"));
417  setUseLabel(false);
418 
419  addChild(new Name(id));
420 
421  Source *source = new Source(id, default_sourceid);
422  source->Load();
423 
425  new HorizontalConfigurationGroup(false,false,true,true);
426  VerticalConfigurationGroup *bottomhoz =
427  new VerticalConfigurationGroup(false, true);
429  new VerticalConfigurationGroup(false, true);
431  new VerticalConfigurationGroup(false, true);
432 
433 
434  left->addChild(new Channum(id));
435  left->addChild(new Callsign(id));
436  left->addChild(new Visible(id));
437 
438  right->addChild(source);
439  right->addChild(new ChannelTVFormat(id));
440  right->addChild(new Priority(id));
441 
442  group1->addChild(left);
443  group1->addChild(right);
444 
445  bottomhoz->addChild(onairguide = new OnAirGuide(id));
446  bottomhoz->addChild(xmltvID = new XmltvID(id, source->getSelectionLabel()));
447  bottomhoz->addChild(new TimeOffset(id));
448 
449  addChild(group1);
450  addChild(new CommMethod(id));
451  addChild(new Icon(id));
452  addChild(bottomhoz);
453 
454  connect(onairguide, SIGNAL(valueChanged( bool)),
455  this, SLOT( onAirGuideChanged(bool)));
456  connect(source, SIGNAL(valueChanged( const QString&)),
457  this, SLOT( sourceChanged(const QString&)));
458 };
459 
461 {
463 }
464 
466 {
467  (void)fValue;
468 }
469 
470 void ChannelOptionsCommon::sourceChanged(const QString& sourceid)
471 {
472  bool supports_eit = true;
473  bool uses_eit_only = false;
474 
475  MSqlQuery query(MSqlQuery::InitCon());
476  query.prepare("SELECT cardtype "
477  "FROM capturecard, videosource, cardinput "
478  "WHERE cardinput.sourceid = videosource.sourceid AND "
479  " cardinput.cardid = capturecard.cardid AND "
480  " videosource.sourceid = :SOURCEID");
481  query.bindValue(":SOURCEID", sourceid);
482 
483  if (!query.exec() || !query.isActive())
484  MythDB::DBError("sourceChanged -- supports eit", query);
485  else
486  {
487  supports_eit = (query.size()) ? false : true;
488  while (query.next())
489  {
490  supports_eit |= CardUtil::IsEITCapable(
491  query.value(0).toString().toUpper());
492  }
493 
494  query.prepare("SELECT xmltvgrabber "
495  "FROM videosource "
496  "WHERE sourceid = :SOURCEID");
497  query.bindValue(":SOURCEID", sourceid);
498 
499  if (!query.exec() || !query.isActive())
500  MythDB::DBError("sourceChanged -- eit only", query);
501  else
502  {
503  uses_eit_only = (query.size()) ? true : false;
504  while (query.next())
505  {
506  uses_eit_only &= (query.value(0).toString() == "eitonly");
507  }
508  }
509  }
510 
511  onairguide->setEnabled(supports_eit);
512  xmltvID->setEnabled(!uses_eit_only);
513  xmltvID->Load();
514 }
515 
518 {
519  setLabel(QObject::tr("Channel Options - Filters"));
520  setUseLabel(false);
521 
522  addChild(new VideoFilters(id));
523  addChild(new OutputFilters(id));
524 }
525 
528 {
529  setLabel(QObject::tr("Channel Options - Video4Linux"));
530  setUseLabel(false);
531 
532  addChild(new Freqid(id));
533  addChild(new Finetune(id));
534  addChild(new Contrast(id));
535  addChild(new Brightness(id));
536  addChild(new Colour(id));
537  addChild(new Hue(id));
538 };
539 
540 /*****************************************************************************
541  Channel Options - Video 4 Linux
542  *****************************************************************************/
543 
546 {
547  setLabel(QObject::tr("Channel Options - Raw Transport Stream"));
548  setUseLabel(false);
549 
550  const uint mx = kMaxPIDs;
551  pids.resize(mx);
552  sids.resize(mx);
553  pcrs.resize(mx);
554 
555  for (uint i = 0; i < mx; i++)
556  {
558  new HorizontalConfigurationGroup(false, false, true, true);
559  TransLabelSetting *label0 = new TransLabelSetting();
560  label0->setLabel(" PID");
561  TransLabelSetting *label1 = new TransLabelSetting();
562  label1->setLabel(" StreamID");
563  TransLabelSetting *label2 = new TransLabelSetting();
564  label2->setLabel(" Is PCR");
565  row->addChild(label0);
566  row->addChild((pids[i] = new TransLineEditSetting()));
567  row->addChild(label1);
568  row->addChild((sids[i] = new TransComboBoxSetting()));
569  for (uint j = 0x101; j <= 0x1ff; j++)
570  {
571  QString desc = StreamID::GetDescription(j&0xff);
572  if (!desc.isEmpty())
573  sids[i]->addSelection(
574  QString("%1 (0x%2)")
575  .arg(desc).arg(j&0xff,2,16,QLatin1Char('0')),
576  QString::number(j), false);
577  }
578  for (uint j = 0x101; j <= 0x1ff; j++)
579  {
580  QString desc = StreamID::GetDescription(j&0xff);
581  if (desc.isEmpty())
582  sids[i]->addSelection(
583  QString("0x%1").arg(j&0xff,2,16,QLatin1Char('0')),
584  QString::number(j), false);
585  }
586 /* we don't allow tables right now, PAT & PMT generated on the fly
587  for (uint j = 0; j <= 0xff; j++)
588  {
589  QString desc = TableID::GetDescription(j);
590  if (!desc.isEmpty())
591  {
592  sids[i]->addSelection(
593  QString("%1 (0x%2)").arg(j,0,16,QLatin1Char('0')),
594  QString::number(j),
595  false);
596  }
597  }
598 */
599  row->addChild(label2);
600  row->addChild((pcrs[i] = new TransCheckBoxSetting()));
601  addChild(row);
602  }
603 };
604 
606 {
607  uint chanid = cid.getValue().toUInt();
608 
609  pid_cache_t pid_cache;
610  if (!ChannelUtil::GetCachedPids(chanid, pid_cache))
611  return;
612 
613  pid_cache_t::const_iterator it = pid_cache.begin();
614  for (uint i = 0; i < kMaxPIDs && it != pid_cache.end(); )
615  {
616  if (!(it->IsPermanent()))
617  {
618  ++it;
619  continue;
620  }
621 
622  pids[i]->setValue(QString("0x%1")
623  .arg(it->GetPID(),2,16,QLatin1Char('0')));
624  sids[i]->setValue(QString::number(it->GetComposite()&0x1ff));
625  pcrs[i]->setValue(it->IsPCRPID());
626 
627  ++it;
628  ++i;
629  }
630 }
631 
633 {
634  uint chanid = cid.getValue().toUInt();
635 
636  pid_cache_t pid_cache;
637  for (uint i = 0; i < kMaxPIDs; i++)
638  {
639  bool ok;
640  uint pid = pids[i]->getValue().toUInt(&ok, 0);
641  if (!ok || !sids[i]->getValue().toUInt())
642  continue;
643 
644  pid_cache.push_back(
646  pid, sids[i]->getValue().toUInt() | 0x10000 |
647  (pcrs[i]->getValue().toUInt() ? 0x200 : 0x0)));
648  }
649 
650  ChannelUtil::SaveCachedPids(chanid, pid_cache, true /* delete_all */);
651 }
652 
653 /* vim: set expandtab tabstop=4 shiftwidth=4: */