MythTV  0.28pre
videosource.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 
3 // Standard UNIX C headers
4 #include <unistd.h>
5 #include <fcntl.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 
9 // C++ headers
10 #include <algorithm>
11 using namespace std;
12 
13 // Qt headers
14 #include <QCoreApplication>
15 #include <QTextStream>
16 #include <QStringList>
17 #include <QCursor>
18 #include <QLayout>
19 #include <QFile>
20 #include <QMap>
21 #include <QDir>
22 #include <QDateTime>
23 
24 // MythTV headers
25 #include "mythconfig.h"
26 #include "mythwidgets.h"
27 #include "mythdialogs.h"
28 #include "mythcorecontext.h"
29 #include "videosource.h"
30 #include "datadirect.h"
31 #include "scanwizard.h"
32 #include "cardutil.h"
33 #include "sourceutil.h"
34 #include "channelinfo.h"
35 #include "channelutil.h"
36 #include "frequencies.h"
37 #include "diseqcsettings.h"
38 #include "firewiredevice.h"
39 #include "compat.h"
40 #include "mythdb.h"
41 #include "mythdirs.h"
42 #include "mythlogging.h"
43 #include "libmythupnp/httprequest.h" // for TestMimeType()
44 #include "mythsystemlegacy.h"
45 #include "exitcodes.h"
46 #include "v4l2util.h"
47 
48 #ifdef USING_DVB
49 #include "dvbtypes.h"
50 #endif
51 
52 #ifdef USING_VBOX
53 #include "vboxutils.h"
54 #endif
55 
56 #ifdef USING_HDHOMERUN
57 #include "hdhomerun.h"
58 #endif
59 
60 static const uint kDefaultMultirecCount = 2;
61 
63  const QString &_card_types,
64  bool _must_have_mplexid) :
65  ComboBoxSetting(this),
66  initial_sourceid(_initial_sourceid),
67  card_types(_card_types),
68  must_have_mplexid(_must_have_mplexid)
69 {
70  card_types.detach();
71  setLabel(tr("Video Source"));
72 }
73 
75 {
77 
78  QString querystr =
79  "SELECT DISTINCT videosource.name, videosource.sourceid "
80  "FROM capturecard, videosource";
81 
82  querystr += (must_have_mplexid) ? ", channel " : " ";
83 
84  querystr +=
85  "WHERE capturecard.sourceid = videosource.sourceid AND "
86  " capturecard.hostname = :HOSTNAME ";
87 
88  if (!card_types.isEmpty())
89  {
90  querystr += QString(" AND capturecard.cardtype in %1 ")
91  .arg(card_types);
92  }
93 
95  {
96  querystr +=
97  " AND channel.sourceid = videosource.sourceid "
98  " AND channel.mplexid != 32767 "
99  " AND channel.mplexid != 0 ";
100  }
101 
102  query.prepare(querystr);
103  query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
104 
105  if (!query.exec() || !query.isActive() || query.size() <= 0)
106  return;
107 
108  uint sel = 0, cnt = 0;
109  for (; query.next(); cnt++)
110  {
111  addSelection(query.value(0).toString(),
112  query.value(1).toString());
113 
114  sel = (query.value(1).toUInt() == initial_sourceid) ? cnt : sel;
115  }
116 
117  if (initial_sourceid)
118  {
119  if (cnt)
120  setValue(sel);
121  setEnabled(false);
122  }
123 }
124 
126 {
127  public:
128  InstanceCount(const CardInput &parent, int _initValue) :
129  SpinBoxSetting(this, 1, 10, _initValue),
130  CardInputDBStorage(this, parent, "reclimit")
131  {
132  setLabel(QObject::tr("Max recordings"));
133  setValue(_initValue);
134  setHelpText(
135  QObject::tr(
136  "Maximum number of simultaneous recordings MythTV will "
137  "attempt using this device. If set to a value other than "
138  "1, MythTV can sometimes record multiple programs on "
139  "the same multiplex or overlapping copies of the same "
140  "program on a single channel."
141  ));
142  };
143 };
144 
146 {
147  public:
148  SchedGroup(const CardInput &parent) :
149  CheckBoxSetting(this),
150  CardInputDBStorage(this, parent, "schedgroup")
151  {
152  setLabel(QObject::tr("Schedule as group"));
153  setValue(false);
154  setHelpText(
155  QObject::tr(
156  "Schedule all virtual inputs on this device as a group. "
157  "This is more efficient than scheduling each input "
158  "individually, but can result in scheduling more "
159  "simultaneous recordings than is allowed. Be sure to set "
160  "the maximum number of simultaneous recordings above "
161  "high enough to handle all expected cases."
162  ));
163  };
164 };
165 
167 {
168  QString sourceidTag(":WHERESOURCEID");
169 
170  QString query("sourceid = " + sourceidTag);
171 
172  bindings.insert(sourceidTag, m_parent.getSourceID());
173 
174  return query;
175 }
176 
178 {
179  QString sourceidTag(":SETSOURCEID");
180  QString colTag(":SET" + GetColumnName().toUpper());
181 
182  QString query("sourceid = " + sourceidTag + ", " +
183  GetColumnName() + " = " + colTag);
184 
185  bindings.insert(sourceidTag, m_parent.getSourceID());
186  bindings.insert(colTag, user->GetDBValue());
187 
188  return query;
189 }
190 
192 {
193  QString cardidTag(":WHERECARDID");
194 
195  QString query("cardid = " + cardidTag);
196 
197  bindings.insert(cardidTag, m_parent.getCardID());
198 
199  return query;
200 }
201 
203 {
204  QString cardidTag(":SETCARDID");
205  QString colTag(":SET" + GetColumnName().toUpper());
206 
207  QString query("cardid = " + cardidTag + ", " +
208  GetColumnName() + " = " + colTag);
209 
210  bindings.insert(cardidTag, m_parent.getCardID());
211  bindings.insert(colTag, user->GetDBValue());
212 
213  return query;
214 }
215 
217 {
218  public:
219  XMLTVGrabber(const VideoSource &parent) :
220  ComboBoxSetting(this),
221  VideoSourceDBStorage(this, parent, "xmltvgrabber")
222  {
223  setLabel(QObject::tr("Listings grabber"));
224  };
225 };
226 
228 {
229  public:
230  DVBNetID(const VideoSource &parent, signed int value, signed int min_val) :
231  SpinBoxSetting(this, min_val, 0xffff, 1),
232  VideoSourceDBStorage(this, parent, "dvb_nit_id")
233  {
234  setLabel(QObject::tr("Network ID"));
235  //: Network_ID is the name of an identifier in the DVB's Service
236  //: Information standard specification.
237  setHelpText(QObject::tr("If your provider has asked you to configure a "
238  "specific network identifier (Network_ID), "
239  "enter it here. Leave it at -1 otherwise."));
240  setValue(value);
241  };
242 };
243 
245  ComboBoxSetting(this), VideoSourceDBStorage(this, parent, "freqtable")
246 {
247  setLabel(QObject::tr("Channel frequency table"));
248  addSelection("default");
249 
250  for (uint i = 0; chanlists[i].name; i++)
252 
253  setHelpText(QObject::tr("Use default unless this source uses a "
254  "different frequency table than the system wide table "
255  "defined in the General settings."));
256 }
257 
259  ComboBoxSetting(this), sourceid(_sourceid),
260  loaded_freq_table(QString::null)
261 {
262  setLabel(QObject::tr("Channel frequency table"));
263 
264  for (uint i = 0; chanlists[i].name; i++)
266 }
267 
269 {
270  int idx = getValueIndex(gCoreContext->GetSetting("FreqTable"));
271  if (idx >= 0)
272  setValue(idx);
273 
274  if (!sourceid)
275  return;
276 
277  MSqlQuery query(MSqlQuery::InitCon());
278  query.prepare(
279  "SELECT freqtable "
280  "FROM videosource "
281  "WHERE sourceid = :SOURCEID");
282  query.bindValue(":SOURCEID", sourceid);
283 
284  if (!query.exec() || !query.isActive())
285  {
286  MythDB::DBError("TransFreqTableSelector::load", query);
287  return;
288  }
289 
290  loaded_freq_table = QString::null;
291 
292  if (query.next())
293  {
294  loaded_freq_table = query.value(0).toString();
295  if (!loaded_freq_table.isEmpty() &&
296  (loaded_freq_table.toLower() != "default"))
297  {
298  int idx = getValueIndex(loaded_freq_table);
299  if (idx >= 0)
300  setValue(idx);
301  }
302  }
303 }
304 
306 {
307  LOG(VB_GENERAL, LOG_INFO, "TransFreqTableSelector::Save(void)");
308 
309  if ((loaded_freq_table == getValue()) ||
310  ((loaded_freq_table.toLower() == "default") &&
311  (getValue() == gCoreContext->GetSetting("FreqTable"))))
312  {
313  return;
314  }
315 
316  MSqlQuery query(MSqlQuery::InitCon());
317  query.prepare(
318  "UPDATE videosource "
319  "SET freqtable = :FREQTABLE "
320  "WHERE sourceid = :SOURCEID");
321 
322  query.bindValue(":FREQTABLE", getValue());
323  query.bindValue(":SOURCEID", sourceid);
324 
325  if (!query.exec() || !query.isActive())
326  {
327  MythDB::DBError("TransFreqTableSelector::load", query);
328  return;
329  }
330 }
331 
333 {
334  sourceid = _sourceid;
335  Load();
336 }
337 
339 {
340  public:
341  UseEIT(const VideoSource &parent) :
342  CheckBoxSetting(this), VideoSourceDBStorage(this, parent, "useeit")
343  {
344  setLabel(QObject::tr("Perform EIT scan"));
345  setHelpText(QObject::tr(
346  "If enabled, program guide data for channels on this "
347  "source will be updated with data provided by the "
348  "channels themselves 'Over-the-Air'."));
349  }
350 };
351 
353 {
354  public:
355  DataDirectUserID(const VideoSource &parent) :
356  LineEditSetting(this), VideoSourceDBStorage(this, parent, "userid")
357  {
358  setLabel(QObject::tr("User ID"));
359  }
360 };
361 
363 {
364  public:
366  LineEditSetting(this, true),
367  VideoSourceDBStorage(this, parent, "password")
368  {
369  SetPasswordEcho(true);
370  setLabel(QObject::tr("Password"));
371  }
372 };
373 
375  const QString &pwd,
376  int _source)
377 {
378  (void) uid;
379  (void) pwd;
380 #ifdef USING_BACKEND
381  if (uid.isEmpty() || pwd.isEmpty())
382  return;
383 
384  qApp->processEvents();
385 
386  DataDirectProcessor ddp(_source, uid, pwd);
387  QString waitMsg = tr("Fetching lineups from %1...")
388  .arg(ddp.GetListingsProviderName());
389 
390  LOG(VB_GENERAL, LOG_INFO, waitMsg);
391  MythProgressDialog *pdlg = new MythProgressDialog(waitMsg, 2);
392 
393  clearSelections();
394 
395  pdlg->setProgress(1);
396 
397  if (!ddp.GrabLineupsOnly())
398  {
399  LOG(VB_GENERAL, LOG_ERR,
400  "DDLS: fillSelections did not successfully load selections");
401  pdlg->deleteLater();
402  return;
403  }
404  const DDLineupList lineups = ddp.GetLineups();
405 
406  DDLineupList::const_iterator it;
407  for (it = lineups.begin(); it != lineups.end(); ++it)
408  addSelection((*it).displayname, (*it).lineupid);
409 
410  pdlg->setProgress(2);
411  pdlg->Close();
412  pdlg->deleteLater();
413 #else // USING_BACKEND
414  LOG(VB_GENERAL, LOG_ERR,
415  "You must compile the backend to set up a DataDirect line-up");
416 #endif // USING_BACKEND
417 }
418 
420 {
422  bool is_sd_userid = userid->getValue().contains('@') > 0;
423  bool match = ((is_sd_userid && (source == DD_SCHEDULES_DIRECT)) ||
424  (!is_sd_userid && (source == DD_ZAP2IT)));
425  if (((userid->getValue() != lastloadeduserid) ||
426  (password->getValue() != lastloadedpassword)) && match)
427  {
428  lineupselector->fillSelections(userid->getValue(),
429  password->getValue(),
430  source);
431  lastloadeduserid = userid->getValue();
432  lastloadedpassword = password->getValue();
433  }
434 }
435 
436 DataDirect_config::DataDirect_config(const VideoSource& _parent, int _source) :
438  parent(_parent)
439 {
440  source = _source;
441 
443  new HorizontalConfigurationGroup(false, false, true, true);
444 
446  addChild(up);
447 
449  new HorizontalConfigurationGroup(false, false, true, true);
450 
452  lp->addChild(button = new DataDirectButton());
453  addChild(lp);
454 
456  addChild(new UseEIT(parent));
457 
458  connect(button, SIGNAL(pressed()),
459  this, SLOT(fillDataDirectLineupSelector()));
460 }
461 
463 {
466 }
467 
469  QString _grabber) :
471  parent(_parent), grabber(_grabber)
472 {
473  QString filename = QString("%1/%2.xmltv")
474  .arg(GetConfDir()).arg(parent.getSourceName());
475 
476  grabberArgs.push_back("--config-file");
477  grabberArgs.push_back(filename);
478  grabberArgs.push_back("--configure");
479 
480  addChild(new UseEIT(parent));
481 
482  TransButtonSetting *config = new TransButtonSetting();
483  config->setLabel(tr("Configure"));
484  config->setHelpText(tr("Run XMLTV configure command."));
485 
486  addChild(config);
487 
488  connect(config, SIGNAL(pressed()), SLOT(RunConfig()));
489 }
490 
492 {
494 #if 0
495  QString err_msg = QObject::tr(
496  "You MUST run 'mythfilldatabase --manual' the first time,\n"
497  "instead of just 'mythfilldatabase'.\nYour grabber does not provide "
498  "channel numbers, so you have to set them manually.");
499 
501  {
502  LOG(VB_GENERAL, LOG_ERR, err_msg);
504  GetMythMainWindow(), QObject::tr("Warning."), err_msg);
505  }
506 #endif
507 }
508 
510 {
512  tw->exec(false, true);
513  delete tw;
514 }
515 
518 {
519  useeit = new UseEIT(_parent);
520  useeit->setValue(true);
521  useeit->setVisible(false);
522  addChild(useeit);
523 
525  label=new TransLabelSetting();
526  label->setValue(QObject::tr("Use only the transmitted guide data."));
527  addChild(label);
528  label=new TransLabelSetting();
529  label->setValue(
530  QObject::tr("This will usually only work with ATSC or DVB channels,"));
531  addChild(label);
532  label=new TransLabelSetting();
533  label->setValue(
534  QObject::tr("and generally provides data only for the next few days."));
535  addChild(label);
536 }
537 
539 {
540  // Force this value on
541  useeit->setValue(true);
542  useeit->Save();
543 }
544 
547 {
548  useeit = new UseEIT(_parent);
549  useeit->setValue(false);
550  useeit->setVisible(false);
551  addChild(useeit);
552 
554  label->setValue(QObject::tr("Do not configure a grabber"));
555  addChild(label);
556 }
557 
559 {
560  useeit->setValue(false);
561  useeit->Save();
562 }
563 
564 
567  parent(aparent), grabber(new XMLTVGrabber(parent))
568 {
569  addChild(grabber);
571 
572  // only save settings for the selected grabber
573  setSaveAll(false);
574 
575 }
576 
578 {
579  addTarget("schedulesdirect1",
581  addTarget("eitonly", new EITOnly_config(parent));
582  addTarget("/bin/true", new NoGrabber_config(parent));
583 
585  QObject::tr("North America (SchedulesDirect.org) (Internal)"),
586  "schedulesdirect1");
587 
589  QObject::tr("Transmitted guide only (EIT)"), "eitonly");
590 
591  grabber->addSelection(QObject::tr("No grabber"), "/bin/true");
592 
593 
594  QString validValues;
595  validValues += "schedulesdirect1";
596  validValues += "eitonly";
597  validValues += "/bin/true";
598 
599  QString gname, d1, d2, d3;
601 
602 #ifdef _MSC_VER
603  #pragma message( "tv_find_grabbers is not supported yet on windows." )
604  //-=>TODO:Screen doesn't show up if the call to MythSysemLegacy is executed
605 #else
606 
607  QString loc = "XMLTVConfig::Load: ";
608  QString loc_err = "XMLTVConfig::Load, Error: ";
609 
610  QStringList name_list;
611  QStringList prog_list;
612 
613  QStringList args;
614  args += "baseline";
615 
616  MythSystemLegacy find_grabber_proc("tv_find_grabbers", args,
618  find_grabber_proc.Run(25);
619  LOG(VB_GENERAL, LOG_INFO,
620  loc + "Running 'tv_find_grabbers " + args.join(" ") + "'.");
621  uint status = find_grabber_proc.Wait();
622 
623  if (status == GENERIC_EXIT_OK)
624  {
625  QTextStream ostream(find_grabber_proc.ReadAll());
626  while (!ostream.atEnd())
627  {
628  QString grabber_list(ostream.readLine());
629  QStringList grabber_split =
630  grabber_list.split("|", QString::SkipEmptyParts);
631  QString grabber_name = grabber_split[1] + " (xmltv)";
632  QFileInfo grabber_file(grabber_split[0]);
633 
634  name_list.push_back(grabber_name);
635  prog_list.push_back(grabber_file.fileName());
636  LOG(VB_GENERAL, LOG_DEBUG, "Found " + grabber_split[0]);
637  }
638  LOG(VB_GENERAL, LOG_INFO, loc + "Finished running tv_find_grabbers");
639  }
640  else
641  LOG(VB_GENERAL, LOG_ERR, loc + "Failed to run tv_find_grabbers");
642 
643  LoadXMLTVGrabbers(name_list, prog_list);
644 #endif
645 
647 
648 }
649 
651  QStringList name_list, QStringList prog_list)
652 {
653  if (name_list.size() != prog_list.size())
654  return;
655 
656  QString selValue = grabber->getValue();
657  int selIndex = grabber->getValueIndex(selValue);
658  grabber->setValue(0);
659 
660  QString validValues;
661  validValues += "schedulesdirect1";
662  validValues += "eitonly";
663  validValues += "/bin/true";
664 
665  for (uint i = 0; i < grabber->size(); i++)
666  {
667  if (!validValues.contains(grabber->GetValue(i)))
668  {
670  i--;
671  }
672  }
673 
674  for (uint i = 0; i < (uint) name_list.size(); i++)
675  {
676  addTarget(prog_list[i],
677  new XMLTV_generic_config(parent, prog_list[i]));
678  grabber->addSelection(name_list[i], prog_list[i]);
679  }
680 
681  if (!selValue.isEmpty())
682  selIndex = grabber->getValueIndex(selValue);
683  if (selIndex >= 0)
684  grabber->setValue(selIndex);
685 
686 }
687 
689 {
691  MSqlQuery query(MSqlQuery::InitCon());
692  query.prepare(
693  "UPDATE videosource "
694  "SET userid=NULL, password=NULL "
695  "WHERE xmltvgrabber NOT IN ( 'datadirect', 'technovera', "
696  " 'schedulesdirect1' )");
697  if (!query.exec())
698  MythDB::DBError("XMLTVConfig::Save", query);
699 }
700 
702 {
703  // must be first
704  addChild(id = new ID());
705 
706  ConfigurationGroup *group = new VerticalConfigurationGroup(false, false);
707  group->setLabel(QObject::tr("Video Source Setup"));
708  group->addChild(name = new Name(*this));
709  group->addChild(xmltv = new XMLTVConfig(*this));
710  group->addChild(new FreqTableSelector(*this));
711  group->addChild(new DVBNetID(*this, -1, -1));
712  addChild(group);
713 }
714 
715 bool VideoSourceEditor::cardTypesInclude(const int &sourceID,
716  const QString &thecardtype)
717 {
718  MSqlQuery query(MSqlQuery::InitCon());
719  query.prepare("SELECT count(cardtype)"
720  " FROM capturecard "
721  " WHERE capturecard.sourceid = :SOURCEID "
722  " AND capturecard.cardtype = :CARDTYPE ;");
723  query.bindValue(":SOURCEID", sourceID);
724  query.bindValue(":CARDTYPE", thecardtype);
725 
726  if (query.exec() && query.next())
727  {
728  int count = query.value(0).toInt();
729 
730  if (count > 0)
731  return true;
732  }
733 
734  return false;
735 }
736 
738 {
739  MSqlQuery result(MSqlQuery::InitCon());
740  result.prepare("SELECT name, sourceid FROM videosource;");
741 
742  if (result.exec() && result.isActive() && result.size() > 0)
743  {
744  while (result.next())
745  {
746  setting->addSelection(result.value(0).toString(),
747  result.value(1).toString());
748  }
749  }
750 }
751 
752 void VideoSource::loadByID(int sourceid)
753 {
754  id->setValue(sourceid);
755 }
756 
758 {
759  public:
761  uint minor_min = 0,
762  uint minor_max = UINT_MAX,
763  QString card = QString::null,
764  QString driver = QString::null) :
765  PathSetting(this, true),
766  CaptureCardDBStorage(this, parent, "videodevice")
767  {
768  setLabel(QObject::tr("Video device"));
769 
770  // /dev/v4l/video*
771  QDir dev("/dev/v4l", "video*", QDir::Name, QDir::System);
772  fillSelectionsFromDir(dev, minor_min, minor_max,
773  card, driver, false);
774 
775  // /dev/video*
776  dev.setPath("/dev");
777  fillSelectionsFromDir(dev, minor_min, minor_max,
778  card, driver, false);
779 
780  // /dev/dtv/video*
781  dev.setPath("/dev/dtv");
782  fillSelectionsFromDir(dev, minor_min, minor_max,
783  card, driver, false);
784 
785  // /dev/dtv*
786  dev.setPath("/dev");
787  dev.setNameFilters(QStringList("dtv*"));
788  fillSelectionsFromDir(dev, minor_min, minor_max,
789  card, driver, false);
790  };
791 
792  void fillSelectionsFromDir(const QDir &dir, bool absPath = true)
793  {
794  fillSelectionsFromDir(dir, 0, 255, QString::null, QString::null, false);
795  }
796 
797  uint fillSelectionsFromDir(const QDir& dir,
798  uint minor_min, uint minor_max,
799  QString card, QString driver,
800  bool allow_duplicates)
801  {
802  uint cnt = 0;
803 
804  QFileInfoList il = dir.entryInfoList();
805  QRegExp *driverExp = NULL;
806  if (!driver.isEmpty())
807  driverExp = new QRegExp(driver);
808 
809  for( QFileInfoList::iterator it = il.begin();
810  it != il.end();
811  ++it )
812  {
813  QFileInfo &fi = *it;
814 
815  struct stat st;
816  QString filepath = fi.absoluteFilePath();
817  int err = lstat(filepath.toLocal8Bit().constData(), &st);
818 
819  if (err)
820  {
821  LOG(VB_GENERAL, LOG_ERR,
822  QString("Could not stat file: %1").arg(filepath));
823  continue;
824  }
825 
826  // is this is a character device?
827  if (!S_ISCHR(st.st_mode))
828  continue;
829 
830  // is this device is in our minor range?
831  uint minor_num = minor(st.st_rdev);
832  if (minor_min > minor_num || minor_max < minor_num)
833  continue;
834 
835  // ignore duplicates if allow_duplicates not set
836  if (!allow_duplicates && minor_list[minor_num])
837  continue;
838 
839  // if the driver returns any info add this device to our list
840  QByteArray tmp = filepath.toLatin1();
841  int videofd = open(tmp.constData(), O_RDWR);
842  if (videofd >= 0)
843  {
844  QString card_name, driver_name;
845  if (CardUtil::GetV4LInfo(videofd, card_name, driver_name) &&
846  (!driverExp || (driverExp->exactMatch(driver_name))) &&
847  (card.isEmpty() || (card_name == card)))
848  {
849  addSelection(filepath);
850  cnt++;
851  }
852  close(videofd);
853  }
854 
855  // add to list of minors discovered to avoid duplicates
856  minor_list[minor_num] = 1;
857  }
858  delete driverExp;
859 
860  return cnt;
861  }
862 
863  QString Driver(void) const { return driver_name; }
864  QString Card(void) const { return card_name; }
865 
866  private:
867  QMap<uint, uint> minor_list;
868  QString card_name;
869  QString driver_name;
870 };
871 
873 {
874  public:
876  PathSetting(this, true),
877  CaptureCardDBStorage(this, parent, "vbidevice")
878  {
879  setLabel(QObject::tr("VBI device"));
880  setFilter(QString::null, QString::null);
881  setHelpText(QObject::tr("Device to read VBI (captions) from."));
882  };
883 
884  void setFilter(const QString &card, const QString &driver)
885  {
886  clearSelections();
887  QDir dev("/dev/v4l", "vbi*", QDir::Name, QDir::System);
888  if (!fillSelectionsFromDir(dev, card, driver))
889  {
890  dev.setPath("/dev");
891  if (!fillSelectionsFromDir(dev, card, driver) &&
892  !getValue().isEmpty())
893  {
894  addSelection(getValue(),getValue(),true);
895  }
896  }
897  }
898 
899  void fillSelectionsFromDir(const QDir &dir, bool absPath = true)
900  {
901  fillSelectionsFromDir(dir, QString::null, QString::null);
902  }
903 
904  uint fillSelectionsFromDir(const QDir &dir, const QString &card,
905  const QString &driver)
906  {
907  QStringList devices;
908  QFileInfoList il = dir.entryInfoList();
909  for( QFileInfoList::iterator it = il.begin();
910  it != il.end();
911  ++it )
912  {
913  QFileInfo &fi = *it;
914 
915  QString device = fi.absoluteFilePath();
916  QByteArray adevice = device.toLatin1();
917  int vbifd = open(adevice.constData(), O_RDWR);
918  if (vbifd < 0)
919  continue;
920 
921  QString cn, dn;
922  if (CardUtil::GetV4LInfo(vbifd, cn, dn) &&
923  (driver.isEmpty() || (dn == driver)) &&
924  (card.isEmpty() || (cn == card)))
925  {
926  devices.push_back(device);
927  }
928 
929  close(vbifd);
930  }
931 
932  QString sel = getValue();
933  for (uint i = 0; i < (uint) devices.size(); i++)
934  addSelection(devices[i], devices[i], devices[i] == sel);
935 
936  return (uint) devices.size();
937  }
938 };
939 
941 {
942  public:
944  LineEditSetting(this, true),
945  CaptureCardDBStorage(this, parent, "audiodevice") // change to arguments
946  {
947  setLabel(QObject::tr("Arguments"));
948  }
949 };
950 
952 {
953  public:
955  PathSetting(this, false),
956  CaptureCardDBStorage(this, parent, "videodevice")
957  {
958  setLabel(QObject::tr("File path"));
959  };
960 };
961 
963 {
964  public:
966  PathSetting(this, false),
967  CaptureCardDBStorage(this, parent, "audiodevice")
968  {
969  setLabel(QObject::tr("Audio device"));
970 #if USING_OSS
971  QDir dev("/dev", "dsp*", QDir::Name, QDir::System);
973  dev.setPath("/dev/sound");
975 #endif
976 #if USING_ALSA
977  addSelection("ALSA:default", "ALSA:default");
978 #endif
979  addSelection(QObject::tr("(None)"), "NULL");
980  setHelpText(QObject::tr("Device to read audio from, "
981  "if audio is separate from the video."));
982  };
983 };
984 
986 {
987  public:
989  SpinBoxSetting(this, min_val, 60000, 250),
990  CaptureCardDBStorage(this, parent, "signal_timeout")
991  {
992  setLabel(QObject::tr("Signal timeout (ms)"));
993  setValue(value);
994  setHelpText(QObject::tr(
995  "Maximum time (in milliseconds) MythTV waits for "
996  "a signal when scanning for channels."));
997  };
998 };
999 
1001 {
1002  public:
1004  SpinBoxSetting(this, min_val, 65000, 250),
1005  CaptureCardDBStorage(this, parent, "channel_timeout")
1006  {
1007  setLabel(QObject::tr("Tuning timeout (ms)"));
1008  setValue(value);
1009  setHelpText(QObject::tr(
1010  "Maximum time (in milliseconds) MythTV waits for "
1011  "a channel lock. For recordings, if this time is "
1012  "exceeded, the recording will be marked as failed."));
1013  };
1014 };
1015 
1017 {
1018  public:
1020  ComboBoxSetting(this),
1021  CaptureCardDBStorage(this, parent, "audioratelimit")
1022  {
1023  setLabel(QObject::tr("Force audio sampling rate"));
1024  setHelpText(
1025  QObject::tr("If non-zero, override the audio sampling "
1026  "rate in the recording profile when this card is "
1027  "used. Use this if your capture card does not "
1028  "support all of the standard rates."));
1029  addSelection(QObject::tr("(None)"), "0");
1030  addSelection("32000");
1031  addSelection("44100");
1032  addSelection("48000");
1033  };
1034 };
1035 
1037 {
1038  public:
1040  CheckBoxSetting(this),
1041  CaptureCardDBStorage(this, parent, "skipbtaudio")
1042  {
1043  setLabel(QObject::tr("Do not adjust volume"));
1044  setHelpText(
1045  QObject::tr("Enable this option for budget BT878 based "
1046  "DVB-T cards such as the AverTV DVB-T which "
1047  "require the audio volume to be left alone."));
1048  };
1049 };
1050 
1052 {
1053  public:
1055  PathSetting(this, true),
1056  CaptureCardDBStorage(this, parent, "videodevice")
1057  {
1058  setLabel(QObject::tr("DVB device"));
1059  setHelpText(
1060  QObject::tr("When you change this setting, the text below "
1061  "should change to the name and type of your card. "
1062  "If the card cannot be opened, an error message "
1063  "will be displayed."));
1064  fillSelections(QString::null);
1065  };
1066 
1070  void fillSelections(const QString &current)
1071  {
1072  clearSelections();
1073 
1074  // Get devices from filesystem
1075  QStringList sdevs = CardUtil::ProbeVideoDevices("DVB");
1076 
1077  // Add current if needed
1078  if (!current.isEmpty() &&
1079  (find(sdevs.begin(), sdevs.end(), current) == sdevs.end()))
1080  {
1081  stable_sort(sdevs.begin(), sdevs.end());
1082  }
1083 
1084  QStringList db = CardUtil::GetVideoDevices("DVB");
1085 
1086  QMap<QString,bool> in_use;
1087  QString sel = current;
1088  for (uint i = 0; i < (uint)sdevs.size(); i++)
1089  {
1090  const QString dev = sdevs[i];
1091  in_use[sdevs[i]] = find(db.begin(), db.end(), dev) != db.end();
1092  if (sel.isEmpty() && !in_use[sdevs[i]])
1093  sel = dev;
1094  }
1095 
1096  if (sel.isEmpty() && sdevs.size())
1097  sel = sdevs[0];
1098 
1099  QString usestr = QString(" -- ");
1100  usestr += QObject::tr("Warning: already in use");
1101 
1102  for (uint i = 0; i < (uint)sdevs.size(); i++)
1103  {
1104  const QString dev = sdevs[i];
1105  QString desc = dev + (in_use[sdevs[i]] ? usestr : "");
1106  desc = (current == sdevs[i]) ? dev : desc;
1107  addSelection(desc, dev, dev == sel);
1108  }
1109  }
1110 
1111  virtual void Load(void)
1112  {
1113  clearSelections();
1114  addSelection(QString::null);
1115 
1117 
1119  fillSelections(dev);
1120  }
1121 };
1122 
1124 {
1125  public:
1127  {
1128  setLabel(QObject::tr("Subtype"));
1129  };
1130 };
1131 
1133 {
1134  public:
1136  {
1137  setLabel(QObject::tr("Frontend ID"));
1138  };
1139 };
1140 
1142 {
1143  public:
1145  CheckBoxSetting(this),
1146  CaptureCardDBStorage(this, parent, "dvb_wait_for_seqstart")
1147  {
1148  setLabel(QObject::tr("Wait for SEQ start header."));
1149  setValue(true);
1150  setHelpText(
1151  QObject::tr("If enabled, drop packets from the start of a DVB "
1152  "recording until a sequence start header is seen."));
1153  };
1154 };
1155 
1157 {
1158  public:
1160  CheckBoxSetting(this),
1161  CaptureCardDBStorage(this, parent, "dvb_on_demand")
1162  {
1163  setLabel(QObject::tr("Open DVB card on demand"));
1164  setValue(true);
1165  setHelpText(
1166  QObject::tr("If enabled, only open the DVB card when required, "
1167  "leaving it free for other programs at other times."));
1168  };
1169 };
1170 
1172 {
1173  public:
1175  CheckBoxSetting(this),
1176  CaptureCardDBStorage(this, parent, "dvb_eitscan")
1177  {
1178  setLabel(QObject::tr("Use DVB card for active EIT scan"));
1179  setValue(true);
1180  setHelpText(
1181  QObject::tr("If enabled, activate active scanning for "
1182  "program data (EIT). When this option is enabled "
1183  "the DVB card is constantly in-use."));
1184  };
1185 };
1186 
1188 {
1189  public:
1191  SpinBoxSetting(this, 0, 2000, 25),
1192  CaptureCardDBStorage(this, parent, "dvb_tuning_delay")
1193  {
1194  setLabel(QObject::tr("DVB tuning delay (ms)"));
1195  setValue(true);
1196  setHelpText(
1197  QObject::tr("Some Linux DVB drivers, in particular for the "
1198  "Hauppauge Nova-T, require that we slow down "
1199  "the tuning process by specifying a delay "
1200  "(in milliseconds)."));
1201  };
1202 };
1203 
1205 {
1206  public:
1208  ComboBoxSetting(this),
1209  CaptureCardDBStorage(this, parent, "videodevice")
1210  {
1211  setLabel(QObject::tr("GUID"));
1212 #ifdef USING_FIREWIRE
1213  vector<AVCInfo> list = FirewireDevice::GetSTBList();
1214  for (uint i = 0; i < list.size(); i++)
1215  {
1216  QString guid = list[i].GetGUIDString();
1217  guid_to_avcinfo[guid] = list[i];
1218  addSelection(guid);
1219  }
1220 #endif // USING_FIREWIRE
1221  }
1222 
1223  AVCInfo GetAVCInfo(const QString &guid) const
1224  { return guid_to_avcinfo[guid]; }
1225 
1226  private:
1227  QMap<QString,AVCInfo> guid_to_avcinfo;
1228 };
1229 
1231  const FirewireGUID *_guid) :
1232  ComboBoxSetting(this),
1233  CaptureCardDBStorage(this, parent, "firewire_model"),
1234  guid(_guid)
1235 {
1236  setLabel(QObject::tr("Cable box model"));
1237  addSelection(QObject::tr("Motorola Generic"), "MOTO GENERIC");
1238  addSelection(QObject::tr("SA/Cisco Generic"), "SA GENERIC");
1239  addSelection("DCH-3200");
1240  addSelection("DCX-3200");
1241  addSelection("DCT-3412");
1242  addSelection("DCT-3416");
1243  addSelection("DCT-6200");
1244  addSelection("DCT-6212");
1245  addSelection("DCT-6216");
1246  addSelection("QIP-6200");
1247  addSelection("QIP-7100");
1248  addSelection("PACE-550");
1249  addSelection("PACE-779");
1250  addSelection("SA3250HD");
1251  addSelection("SA4200HD");
1252  addSelection("SA4250HDC");
1253  addSelection("SA8300HD");
1254  QString help = QObject::tr(
1255  "Choose the model that most closely resembles your set top box. "
1256  "Depending on firmware revision SA4200HD may work better for a "
1257  "SA3250HD box.");
1258  setHelpText(help);
1259 }
1260 
1261 void FirewireModel::SetGUID(const QString &_guid)
1262 {
1263  (void) _guid;
1264 
1265 #ifdef USING_FIREWIRE
1266  AVCInfo info = guid->GetAVCInfo(_guid);
1267  QString model = FirewireDevice::GetModelName(info.vendorid, info.modelid);
1268  setValue(max(getValueIndex(model), 0));
1269 #endif // USING_FIREWIRE
1270 }
1271 
1272 void FirewireDesc::SetGUID(const QString &_guid)
1273 {
1274  (void) _guid;
1275 
1276  setLabel(tr("Description"));
1277 
1278 #ifdef USING_FIREWIRE
1279  QString name = guid->GetAVCInfo(_guid).product_name;
1280  name.replace("Scientific-Atlanta", "SA");
1281  name.replace(", Inc.", "");
1282  name.replace("Explorer(R)", "");
1283  name = name.simplified();
1284  setValue((name.isEmpty()) ? "" : name);
1285 #endif // USING_FIREWIRE
1286 }
1287 
1289 {
1290  public:
1292  ComboBoxSetting(this),
1293  CaptureCardDBStorage(this, parent, "firewire_connection")
1294  {
1295  setLabel(QObject::tr("Connection Type"));
1296  addSelection(QObject::tr("Point to Point"),"0");
1297  addSelection(QObject::tr("Broadcast"),"1");
1298  }
1299 };
1300 
1302 {
1303  public:
1304  FirewireSpeed(const CaptureCard &parent) :
1305  ComboBoxSetting(this),
1306  CaptureCardDBStorage(this, parent, "firewire_speed")
1307  {
1308  setLabel(QObject::tr("Speed"));
1309  addSelection(QObject::tr("100Mbps"),"0");
1310  addSelection(QObject::tr("200Mbps"),"1");
1311  addSelection(QObject::tr("400Mbps"),"2");
1312  addSelection(QObject::tr("800Mbps"),"3");
1313  }
1314 };
1315 
1317 {
1318  public:
1321  parent(a_parent),
1322  dev(new FirewireGUID(parent)),
1323  desc(new FirewireDesc(dev)),
1324  model(new FirewireModel(parent, dev))
1325  {
1326  addChild(dev);
1327  addChild(new EmptyAudioDevice(parent));
1328  addChild(new EmptyVBIDevice(parent));
1329  addChild(desc);
1330  addChild(model);
1331 
1332 #ifdef USING_LINUX_FIREWIRE
1333  addChild(new FirewireConnection(parent));
1334  addChild(new FirewireSpeed(parent));
1335 #endif // USING_LINUX_FIREWIRE
1336 
1337  addChild(new SignalTimeout(parent, 2000, 1000));
1338  addChild(new ChannelTimeout(parent, 9000, 1750));
1339 
1340  model->SetGUID(dev->getValue());
1341  desc->SetGUID(dev->getValue());
1342  connect(dev, SIGNAL(valueChanged(const QString&)),
1343  model, SLOT( SetGUID( const QString&)));
1344  connect(dev, SIGNAL(valueChanged(const QString&)),
1345  desc, SLOT( SetGUID( const QString&)));
1346  };
1347 
1348  private:
1353 };
1354 
1355 // -----------------------
1356 // HDHomeRun Configuration
1357 // -----------------------
1358 
1360 {
1361  setLabel(QObject::tr("IP Address"));
1362  setEnabled(false);
1363  connect(this, SIGNAL(valueChanged( const QString&)),
1364  this, SLOT( UpdateDevices(const QString&)));
1365  _oldValue="";
1366 };
1367 
1369 {
1371  if (e)
1372  {
1373  if (!_oldValue.isEmpty())
1374  setValue(_oldValue);
1375  emit NewIP(getValue());
1376  }
1377  else
1378  {
1379  _oldValue = getValue();
1380  _oldValue.detach();
1381  }
1382 }
1383 
1384 void HDHomeRunIP::UpdateDevices(const QString &v)
1385 {
1386  if (isEnabled())
1387  {
1388 #if 0
1389  LOG(VB_GENERAL, LOG_DEBUG, QString("Emitting NewIP(%1)").arg(v));
1390 #endif
1391  emit NewIP(v);
1392  }
1393 }
1394 
1396 {
1397  setLabel(QObject::tr("Tuner"));
1398  setEnabled(false);
1399  connect(this, SIGNAL(valueChanged( const QString&)),
1400  this, SLOT( UpdateDevices(const QString&)));
1401  _oldValue = "";
1402 };
1403 
1405 {
1407  if (e) {
1408  if (!_oldValue.isEmpty())
1409  setValue(_oldValue);
1410  emit NewTuner(getValue());
1411  }
1412  else
1413  {
1414  _oldValue = getValue();
1415  }
1416 }
1417 
1419 {
1420  if (isEnabled())
1421  {
1422 #if 0
1423  LOG(VB_GENERAL, LOG_DEBUG, QString("Emitting NewTuner(%1)").arg(v));
1424 #endif
1425  emit NewTuner(v);
1426  }
1427 }
1428 
1430  LabelSetting(this),
1431  CaptureCardDBStorage(this, parent, "videodevice"),
1432  _ip(QString::null),
1433  _tuner(QString::null),
1434  _overridedeviceid(QString::null)
1435 {
1436  setLabel(tr("Device ID"));
1437  setHelpText(tr("Device ID of HDHomeRun device"));
1438 }
1439 
1440 void HDHomeRunDeviceID::SetIP(const QString &ip)
1441 {
1442 #if 0
1443  LOG(VB_GENERAL, LOG_DEBUG, QString("Setting IP to %1").arg(ip));
1444 #endif
1445  _ip = ip;
1446  setValue(QString("%1-%2").arg(_ip).arg(_tuner));
1447 #if 0
1448  LOG(VB_GENERAL, LOG_DEBUG, QString("Done Setting IP to %1").arg(ip));
1449 #endif
1450 }
1451 
1452 void HDHomeRunDeviceID::SetTuner(const QString &tuner)
1453 {
1454 #if 0
1455  LOG(VB_GENERAL, LOG_DEBUG, QString("Setting Tuner to %1").arg(tuner));
1456 #endif
1457  _tuner = tuner;
1458  setValue(QString("%1-%2").arg(_ip).arg(_tuner));
1459 #if 0
1460  LOG(VB_GENERAL, LOG_DEBUG, QString("Done Setting Tuner to %1").arg(tuner));
1461 #endif
1462 }
1463 
1464 void HDHomeRunDeviceID::SetOverrideDeviceID(const QString &deviceid)
1465 {
1466  _overridedeviceid = deviceid;
1467  setValue(deviceid);
1468 }
1469 
1471 {
1473  if (!_overridedeviceid.isEmpty())
1474  {
1476  _overridedeviceid = QString::null;
1477  }
1478 }
1479 
1481  HDHomeRunDeviceID *deviceid,
1482  TransLabelSetting *desc,
1483  HDHomeRunIP *cardip,
1484  HDHomeRunTunerIndex *cardtuner,
1485  HDHomeRunDeviceList *devicelist) :
1486  _deviceid(deviceid),
1487  _desc(desc),
1488  _cardip(cardip),
1489  _cardtuner(cardtuner),
1490  _devicelist(devicelist)
1491 {
1492  setLabel(QObject::tr("Available devices"));
1493  setHelpText(
1494  QObject::tr(
1495  "Device ID and Tuner Number of available HDHomeRun devices."));
1496 
1497  connect(this, SIGNAL(valueChanged( const QString&)),
1498  this, SLOT( UpdateDevices(const QString&)));
1499 
1500  _oldValue = "";
1501 };
1502 
1507 {
1508  clearSelections();
1509 
1510  vector<QString> devs;
1511  QMap<QString, bool> in_use;
1512 
1513  QString current = cur;
1514 
1515 #if 0
1516  LOG(VB_GENERAL, LOG_DEBUG, QString("Filling List, current = '%1'")
1517  .arg(current));
1518 #endif
1519 
1520  HDHomeRunDeviceList::iterator it = _devicelist->begin();
1521  for (; it != _devicelist->end(); ++it)
1522  {
1523  if ((*it).discovered)
1524  {
1525  devs.push_back(it.key());
1526  in_use[it.key()] = (*it).inuse;
1527  }
1528  }
1529 
1530  QString man_addr = HDHomeRunDeviceIDList::tr("Manually Enter IP Address");
1531  QString sel = man_addr;
1532  devs.push_back(sel);
1533 
1534  if (3 == devs.size() && current.startsWith("FFFFFFFF", Qt::CaseInsensitive))
1535  {
1536  current = sel = (current.endsWith("0")) ?
1537  *(devs.begin()) : *(++devs.begin());
1538  }
1539  else
1540  {
1541  vector<QString>::const_iterator it = devs.begin();
1542  for (; it != devs.end(); ++it)
1543  sel = (current == *it) ? *it : sel;
1544  }
1545 
1546  QString usestr = QString(" -- ");
1547  usestr += QObject::tr("Warning: already in use");
1548 
1549  for (uint i = 0; i < devs.size(); i++)
1550  {
1551  const QString dev = devs[i];
1552  QString desc = dev + (in_use[devs[i]] ? usestr : "");
1553  desc = (current == devs[i]) ? dev : desc;
1554  addSelection(desc, dev, dev == sel);
1555  }
1556 
1557  if (current != cur)
1558  {
1559  _deviceid->SetOverrideDeviceID(current);
1560  }
1561  else if (sel == man_addr && !current.isEmpty())
1562  {
1563  // Populate the proper values for IP address and tuner
1564  QStringList selection = current.split("-");
1565 
1566  _cardip->SetOldValue(selection.first());
1567  _cardtuner->SetOldValue(selection.last());
1568 
1569  _cardip->setValue(selection.first());
1570  _cardtuner->setValue(selection.last());
1571  }
1572 }
1573 
1575 {
1576  clearSelections();
1577 
1579 }
1580 
1582 {
1583 #if 0
1584  LOG(VB_GENERAL, LOG_DEBUG, QString("Got signal with %1").arg(v));
1585 #endif
1586  if (v == HDHomeRunDeviceIDList::tr("Manually Enter IP Address"))
1587  {
1588  _cardip->setEnabled(true);
1589  _cardtuner->setEnabled(true);
1590 #if 0
1591  LOG(VB_GENERAL, LOG_DEBUG, "Done");
1592 #endif
1593  }
1594  else if (!v.isEmpty())
1595  {
1596  if (_oldValue == HDHomeRunDeviceIDList::tr("Manually Enter IP Address"))
1597  {
1598  _cardip->setEnabled(false);
1599  _cardtuner->setEnabled(false);
1600  }
1601  _deviceid->setValue(v);
1602 
1603  // Update _cardip and cardtuner
1604  _cardip->setValue((*_devicelist)[v].cardip);
1605  _cardtuner->setValue(QString("%1").arg((*_devicelist)[v].cardtuner));
1606  _desc->setValue((*_devicelist)[v].desc);
1607  }
1608  _oldValue = v;
1609 };
1610 
1611 // -----------------------
1612 // VBOX Configuration
1613 // -----------------------
1614 
1616 {
1617  setLabel(QObject::tr("IP Address"));
1618  setHelpText(QObject::tr("Device IP or ID of a VBox device. eg. '192.168.1.100' or 'vbox_3718'"));
1619  setEnabled(false);
1620  connect(this, SIGNAL(valueChanged(const QString&)),
1621  this, SLOT(UpdateDevices(const QString&)));
1622  _oldValue="";
1623 };
1624 
1626 {
1628  if (e)
1629  {
1630  if (!_oldValue.isEmpty())
1632  emit NewIP(getValue());
1633  }
1634  else
1635  {
1636  _oldValue = getValue();
1637  _oldValue.detach();
1638  }
1639 }
1640 
1641 void VBoxIP::UpdateDevices(const QString &v)
1642 {
1643  if (isEnabled())
1644  emit NewIP(v);
1645 }
1646 
1648 {
1649  setLabel(QObject::tr("Tuner"));
1650  setHelpText(QObject::tr("Number and type of the tuner to use. eg '1-DVBT/T2'."));
1651  setEnabled(false);
1652  connect(this, SIGNAL(valueChanged(const QString&)),
1653  this, SLOT(UpdateDevices(const QString&)));
1654  _oldValue = "";
1655 };
1656 
1658 {
1660  if (e) {
1661  if (!_oldValue.isEmpty())
1663  emit NewTuner(getValue());
1664  }
1665  else
1666  {
1667  _oldValue = getValue();
1668  }
1669 }
1670 
1671 void VBoxTunerIndex::UpdateDevices(const QString &v)
1672 {
1673  if (isEnabled())
1674  emit NewTuner(v);
1675 }
1676 
1678  LabelSetting(this),
1679  CaptureCardDBStorage(this, parent, "videodevice"),
1680  _ip(QString::null),
1681  _tuner(QString::null),
1682  _overridedeviceid(QString::null)
1683 {
1684  setLabel(tr("Device ID"));
1685  setHelpText(tr("Device ID of VBox device"));
1686 }
1687 
1688 void VBoxDeviceID::SetIP(const QString &ip)
1689 {
1690  _ip = ip;
1691  setValue(QString("%1-%2").arg(_ip).arg(_tuner));
1692 }
1693 
1694 void VBoxDeviceID::SetTuner(const QString &tuner)
1695 {
1696  _tuner = tuner;
1697  setValue(QString("%1-%2").arg(_ip).arg(_tuner));
1698 }
1699 
1700 void VBoxDeviceID::SetOverrideDeviceID(const QString &deviceid)
1701 {
1702  _overridedeviceid = deviceid;
1703  setValue(deviceid);
1704 }
1705 
1707 {
1709  if (!_overridedeviceid.isEmpty())
1710  {
1712  _overridedeviceid = QString::null;
1713  }
1714 }
1715 
1717  VBoxDeviceID *deviceid,
1718  TransLabelSetting *desc,
1719  VBoxIP *cardip,
1720  VBoxTunerIndex *cardtuner,
1721  VBoxDeviceList *devicelist) :
1722  _deviceid(deviceid),
1723  _desc(desc),
1724  _cardip(cardip),
1725  _cardtuner(cardtuner),
1726  _devicelist(devicelist)
1727 {
1728  setLabel(QObject::tr("Available devices"));
1729  setHelpText(
1730  QObject::tr(
1731  "Device IP or ID, tuner number and tuner type of available VBox devices."));
1732 
1733  connect(this, SIGNAL(valueChanged(const QString&)),
1734  this, SLOT(UpdateDevices(const QString&)));
1735 
1736  _oldValue = "";
1737 };
1738 
1740 void VBoxDeviceIDList::fillSelections(const QString &cur)
1741 {
1742  clearSelections();
1743 
1744  vector<QString> devs;
1745  QMap<QString, bool> in_use;
1746 
1747  QString current = cur;
1748 
1749  VBoxDeviceList::iterator it = _devicelist->begin();
1750  for (; it != _devicelist->end(); ++it)
1751  {
1752  devs.push_back(it.key());
1753  in_use[it.key()] = (*it).inuse;
1754  }
1755 
1756  QString man_addr = VBoxDeviceIDList::tr("Manually Enter IP Address");
1757  QString sel = man_addr;
1758  devs.push_back(sel);
1759 
1760  vector<QString>::const_iterator it2 = devs.begin();
1761  for (; it2 != devs.end(); ++it2)
1762  sel = (current == *it2) ? *it2 : sel;
1763 
1764  QString usestr = QString(" -- ");
1765  usestr += QObject::tr("Warning: already in use");
1766 
1767  for (uint i = 0; i < devs.size(); i++)
1768  {
1769  const QString dev = devs[i];
1770  QString desc = dev + (in_use[devs[i]] ? usestr : "");
1771  addSelection(desc, dev, dev == sel);
1772  }
1773 
1774  if (current != cur)
1775  {
1776  _deviceid->SetOverrideDeviceID(current);
1777  }
1778  else if (sel == man_addr && !current.isEmpty())
1779  {
1780  // Populate the proper values for IP address and tuner
1781  QStringList selection = current.split("-");
1782 
1783  _cardip->SetOldValue(selection.first());
1784  _cardtuner->SetOldValue(selection.last());
1785 
1786  _cardip->setValue(selection.first());
1787  _cardtuner->setValue(selection.last());
1788  }
1789 }
1790 
1792 {
1793  clearSelections();
1794 
1796 }
1797 
1798 void VBoxDeviceIDList::UpdateDevices(const QString &v)
1799 {
1800  if (v == VBoxDeviceIDList::tr("Manually Enter IP Address"))
1801  {
1802  _cardip->setEnabled(true);
1803  _cardtuner->setEnabled(true);
1804  }
1805  else if (!v.isEmpty())
1806  {
1807  if (_oldValue == VBoxDeviceIDList::tr("Manually Enter IP Address"))
1808  {
1809  _cardip->setEnabled(false);
1810  _cardtuner->setEnabled(false);
1811  }
1812  _deviceid->setValue(v);
1813 
1814  // Update _cardip and _cardtuner
1815  _cardip->setValue((*_devicelist)[v].cardip);
1816  _cardtuner->setValue(QString("%1").arg((*_devicelist)[v].tunerno));
1817  _desc->setValue((*_devicelist)[v].desc);
1818  }
1819  _oldValue = v;
1820 };
1821 
1822 // -----------------------
1823 // IPTV Configuration
1824 // -----------------------
1825 
1827 {
1828  public:
1829  IPTVHost(const CaptureCard &parent) :
1830  LineEditSetting(this),
1831  CaptureCardDBStorage(this, parent, "videodevice")
1832  {
1833  setValue("http://mafreebox.freebox.fr/freeboxtv/playlist.m3u");
1834  setLabel(QObject::tr("M3U URL"));
1835  setHelpText(
1836  QObject::tr("URL of M3U containing RTSP/RTP/UDP channel URLs."));
1837  }
1838 };
1839 
1841 {
1842  public:
1845  parent(a_parent)
1846  {
1847  setUseLabel(false);
1848  addChild(new IPTVHost(parent));
1849  addChild(new ChannelTimeout(parent, 30000, 1750));
1850  addChild(new EmptyAudioDevice(parent));
1851  addChild(new EmptyVBIDevice(parent));
1852  };
1853 
1854  private:
1856 };
1857 
1859 {
1860  public:
1861  ASIDevice(const CaptureCard &parent) :
1862  ComboBoxSetting(this, true),
1863  CaptureCardDBStorage(this, parent, "videodevice")
1864  {
1865  setLabel(QObject::tr("ASI device"));
1866  fillSelections(QString::null);
1867  };
1868 
1872  void fillSelections(const QString &current)
1873  {
1874  clearSelections();
1875 
1876  // Get devices from filesystem
1877  QStringList sdevs = CardUtil::ProbeVideoDevices("ASI");
1878 
1879  // Add current if needed
1880  if (!current.isEmpty() &&
1881  (find(sdevs.begin(), sdevs.end(), current) == sdevs.end()))
1882  {
1883  stable_sort(sdevs.begin(), sdevs.end());
1884  }
1885 
1886  // Get devices from DB
1887  QStringList db = CardUtil::GetVideoDevices("ASI");
1888 
1889  // Figure out which physical devices are already in use
1890  // by another card defined in the DB, and select a device
1891  // for new configs (preferring non-conflicing devices).
1892  QMap<QString,bool> in_use;
1893  QString sel = current;
1894  for (uint i = 0; i < (uint)sdevs.size(); i++)
1895  {
1896  const QString dev = sdevs[i];
1897  in_use[sdevs[i]] = find(db.begin(), db.end(), dev) != db.end();
1898  if (sel.isEmpty() && !in_use[sdevs[i]])
1899  sel = dev;
1900  }
1901 
1902  // Unfortunately all devices are conflicted, select first device.
1903  if (sel.isEmpty() && sdevs.size())
1904  sel = sdevs[0];
1905 
1906  QString usestr = QString(" -- ");
1907  usestr += QObject::tr("Warning: already in use");
1908 
1909  // Add the devices to the UI
1910  bool found = false;
1911  for (uint i = 0; i < (uint)sdevs.size(); i++)
1912  {
1913  const QString dev = sdevs[i];
1914  QString desc = dev + (in_use[sdevs[i]] ? usestr : "");
1915  desc = (current == sdevs[i]) ? dev : desc;
1916  addSelection(desc, dev, dev == sel);
1917  found |= (dev == sel);
1918  }
1919 
1920  // If a configured device isn't on the list, add it with warning
1921  if (!found && !current.isEmpty())
1922  {
1923  QString desc = current + " -- " +
1924  QObject::tr("Warning: unable to open");
1925  addSelection(desc, current, true);
1926  }
1927  }
1928 
1929  virtual void Load(void)
1930  {
1931  clearSelections();
1932  addSelection(QString::null);
1935  }
1936 };
1937 
1940  parent(a_parent),
1941  device(new ASIDevice(parent)),
1942  cardinfo(new TransLabelSetting())
1943 {
1944  addChild(device);
1947  addChild(cardinfo);
1948 
1949  connect(device, SIGNAL(valueChanged(const QString&)),
1950  this, SLOT( probeCard( const QString&)));
1951 
1953 };
1954 
1956 {
1957 #ifdef USING_ASI
1958  if (device.isEmpty())
1959  {
1960  cardinfo->setValue("");
1961  return;
1962  }
1963 
1964  if (parent.getCardID() && parent.GetRawCardType() != "ASI")
1965  {
1966  cardinfo->setValue("");
1967  return;
1968  }
1969 
1970  QString error;
1971  int device_num = CardUtil::GetASIDeviceNumber(device, &error);
1972  if (device_num < 0)
1973  {
1974  cardinfo->setValue(tr("Not a valid DVEO ASI card"));
1975  LOG(VB_GENERAL, LOG_WARNING,
1976  "ASIConfigurationGroup::probeCard(), Warning: " + error);
1977  return;
1978  }
1979  cardinfo->setValue(tr("Valid DVEO ASI card"));
1980 #else
1981  cardinfo->setValue(QString("Not compiled with ASI support"));
1982 #endif
1983 }
1984 
1987  parent(a_parent),
1988  info(new TransLabelSetting()), size(new TransLabelSetting())
1989 {
1990  FileDevice *device = new FileDevice(parent);
1991  device->setHelpText(tr("A local file used to simulate a recording."
1992  " Leave empty to use MythEvents to trigger an"
1993  " external program to import recording files."));
1994  addChild(device);
1995 
1998 
1999  info->setLabel(tr("File info"));
2000  addChild(info);
2001 
2002  size->setLabel(tr("File size"));
2003  addChild(size);
2004 
2005  connect(device, SIGNAL(valueChanged(const QString&)),
2006  this, SLOT( probeCard( const QString&)));
2007 
2008  probeCard(device->getValue());
2009 };
2010 
2011 void ImportConfigurationGroup::probeCard(const QString &device)
2012 {
2013  QString ci, cs;
2014  QFileInfo fileInfo(device);
2015 
2016  // For convenience, ImportRecorder allows both formats:
2017  if (device.toLower().startsWith("file:"))
2018  fileInfo.setFile(device.mid(5));
2019 
2020  if (fileInfo.exists())
2021  {
2022  if (fileInfo.isReadable() && (fileInfo.isFile()))
2023  {
2024  ci = HTTPRequest::TestMimeType(fileInfo.absoluteFilePath());
2025  cs = tr("%1 MB").arg(fileInfo.size() / 1024 / 1024);
2026  }
2027  else
2028  ci = tr("File not readable");
2029  }
2030  else
2031  {
2032  ci = tr("File %1 does not exist").arg(device);
2033  }
2034 
2035  info->setValue(ci);
2036  size->setValue(cs);
2037 }
2038 
2040 {
2041  public:
2043 };
2044 
2046 {
2048  rec->setLabel(QObject::tr("Recorder Options"));
2049  rec->setUseLabel(false);
2050 
2051  rec->addChild(new SignalTimeout(parent.parent, 1000, 250));
2052  rec->addChild(new ChannelTimeout(parent.parent, 3000, 1750));
2053 
2054  addChild(rec);
2055 }
2056 
2058  (CaptureCard& a_parent) :
2059  VerticalConfigurationGroup(false, true, false, false),
2060  parent(a_parent)
2061 {
2062  setUseLabel(false);
2063 
2064  // Fill Device list
2065  FillDeviceList();
2066 
2067  deviceid = new HDHomeRunDeviceID(parent);
2068  desc = new TransLabelSetting();
2069  desc->setLabel(tr("Description"));
2070  cardip = new HDHomeRunIP();
2071  cardtuner = new HDHomeRunTunerIndex();
2072  deviceidlist = new HDHomeRunDeviceIDList(
2073  deviceid, desc, cardip, cardtuner, &devicelist);
2074 
2075  addChild(deviceidlist);
2078  addChild(deviceid);
2079  addChild(desc);
2080  addChild(cardip);
2081  addChild(cardtuner);
2082 
2083  TransButtonSetting *buttonRecOpt = new TransButtonSetting();
2084  buttonRecOpt->setLabel(tr("Recording Options"));
2085  addChild(buttonRecOpt);
2086 
2087  connect(buttonRecOpt, SIGNAL(pressed()),
2088  this, SLOT( HDHomeRunExtraPanel()));
2089 
2090  connect(cardip, SIGNAL(NewIP(const QString&)),
2091  deviceid, SLOT( SetIP(const QString&)));
2092  connect(cardtuner, SIGNAL(NewTuner(const QString&)),
2093  deviceid, SLOT( SetTuner(const QString&)));
2094 };
2095 
2097 {
2098  devicelist.clear();
2099 
2100  // Find physical devices first
2101  // ProbeVideoDevices returns "deviceid ip" pairs
2102  QStringList devs = CardUtil::ProbeVideoDevices("HDHOMERUN");
2103 
2104  QStringList::const_iterator it;
2105 
2106  for (it = devs.begin(); it != devs.end(); ++it)
2107  {
2108  QString dev = *it;
2109  QStringList devinfo = dev.split(" ");
2110  QString devid = devinfo.at(0);
2111  QString devip = devinfo.at(1);
2112  QString devtuner = devinfo.at(2);
2113 
2114  HDHomeRunDevice tmpdevice;
2115  tmpdevice.deviceid = devid;
2116  tmpdevice.desc = CardUtil::GetHDHRdesc(devid);
2117  tmpdevice.cardip = devip;
2118  tmpdevice.inuse = false;
2119  tmpdevice.discovered = true;
2120  tmpdevice.cardtuner = devtuner;
2121  tmpdevice.mythdeviceid =
2122  tmpdevice.deviceid + "-" + tmpdevice.cardtuner;
2123  devicelist[tmpdevice.mythdeviceid] = tmpdevice;
2124  }
2125  uint found_device_count = devicelist.size();
2126 
2127  // Now find configured devices
2128 
2129  // returns "xxxxxxxx-n" or "ip.ip.ip.ip-n" values
2130  QStringList db = CardUtil::GetVideoDevices("HDHOMERUN");
2131 
2132  for (it = db.begin(); it != db.end(); ++it)
2133  {
2134  QMap<QString, HDHomeRunDevice>::iterator dit;
2135 
2136  dit = devicelist.find(*it);
2137 
2138  if (dit == devicelist.end())
2139  {
2140  if ((*it).toUpper() == "FFFFFFFF-0" && 2 == found_device_count)
2141  dit = devicelist.begin();
2142 
2143  if ((*it).toUpper() == "FFFFFFFF-1" && 2 == found_device_count)
2144  {
2145  dit = devicelist.begin();
2146  ++dit;
2147  }
2148  }
2149 
2150  if (dit != devicelist.end())
2151  {
2152  (*dit).inuse = true;
2153  continue;
2154  }
2155 
2156  HDHomeRunDevice tmpdevice;
2157  tmpdevice.mythdeviceid = *it;
2158  tmpdevice.inuse = true;
2159  tmpdevice.discovered = false;
2160 
2161  if (ProbeCard(tmpdevice))
2162  devicelist[tmpdevice.mythdeviceid] = tmpdevice;
2163  }
2164 
2165 #if 0
2166  // Debug dump of cards
2167  QMap<QString, HDHomeRunDevice>::iterator debugit;
2168  for (debugit = devicelist.begin(); debugit != devicelist.end(); ++debugit)
2169  {
2170  LOG(VB_GENERAL, LOG_DEBUG, QString("%1: %2 %3 %4 %5 %6 %7")
2171  .arg(debugit.key())
2172  .arg((*debugit).mythdeviceid)
2173  .arg((*debugit).deviceid)
2174  .arg((*debugit).cardip)
2175  .arg((*debugit).cardtuner)
2176  .arg((*debugit).inuse)
2177  .arg((*debugit).discovered));
2178  }
2179 #endif
2180 }
2181 
2183 {
2184 #ifdef USING_HDHOMERUN
2185  hdhomerun_device_t *thisdevice =
2186  hdhomerun_device_create_from_str(
2187  tmpdevice.mythdeviceid.toLocal8Bit().constData(), NULL);
2188 
2189  if (thisdevice)
2190  {
2191  uint device_id = hdhomerun_device_get_device_id(thisdevice);
2192  uint device_ip = hdhomerun_device_get_device_ip(thisdevice);
2193  uint tuner = hdhomerun_device_get_tuner(thisdevice);
2194  hdhomerun_device_destroy(thisdevice);
2195 
2196  if (device_id == 0)
2197  tmpdevice.deviceid = "NOTFOUND";
2198  else
2199  {
2200  tmpdevice.deviceid = QString("%1").arg(device_id, 8, 16);
2201  tmpdevice.desc = CardUtil::GetHDHRdesc(tmpdevice.deviceid);
2202  }
2203 
2204  tmpdevice.deviceid = tmpdevice.deviceid.toUpper();
2205 
2206  tmpdevice.cardip = QString("%1.%2.%3.%4")
2207  .arg((device_ip>>24) & 0xFF).arg((device_ip>>16) & 0xFF)
2208  .arg((device_ip>> 8) & 0xFF).arg((device_ip>> 0) & 0xFF);
2209 
2210  tmpdevice.cardtuner = QString("%1").arg(tuner);
2211  return true;
2212  }
2213 #endif // USING_HDHOMERUN
2214  return false;
2215 }
2216 
2218 {
2219  parent.reload(); // ensure card id is valid
2220 
2221  HDHomeRunExtra acw(*this);
2222  acw.exec();
2223 }
2224 
2225 // -----------------------
2226 // VBox Configuration
2227 // -----------------------
2228 
2230 {
2231  public:
2233 };
2234 
2236 {
2238  rec->setLabel(QObject::tr("Recorder Options"));
2239  rec->setUseLabel(false);
2240 
2241  rec->addChild(new SignalTimeout(parent.parent, 1000, 250));
2242  rec->addChild(new ChannelTimeout(parent.parent, 3000, 1750));
2243 
2244  addChild(rec);
2245 }
2246 
2248  (CaptureCard& a_parent) :
2249  VerticalConfigurationGroup(false, true, false, false),
2250  parent(a_parent)
2251 {
2252  setUseLabel(false);
2253 
2254  // Fill Device list
2255  FillDeviceList();
2256 
2257  deviceid = new VBoxDeviceID(parent);
2258  desc = new TransLabelSetting();
2259  desc->setLabel(tr("Description"));
2260  cardip = new VBoxIP();
2261  cardtuner = new VBoxTunerIndex();
2262  deviceidlist = new VBoxDeviceIDList(
2263  deviceid, desc, cardip, cardtuner, &devicelist);
2264 
2265  addChild(deviceidlist);
2268  addChild(deviceid);
2269  addChild(desc);
2270  addChild(cardip);
2271  addChild(cardtuner);
2272 
2273  TransButtonSetting *buttonRecOpt = new TransButtonSetting();
2274  buttonRecOpt->setLabel(tr("Recording Options"));
2275  addChild(buttonRecOpt);
2276 
2277  connect(buttonRecOpt, SIGNAL(pressed()),
2278  this, SLOT( VBoxExtraPanel()));
2279 
2280  connect(cardip, SIGNAL(NewIP(const QString&)),
2281  deviceid, SLOT( SetIP(const QString&)));
2282  connect(cardtuner, SIGNAL(NewTuner(const QString&)),
2283  deviceid, SLOT( SetTuner(const QString&)));
2284 };
2285 
2287 {
2288  devicelist.clear();
2289 
2290  // Find physical devices first
2291  // ProbeVideoDevices returns "deviceid ip tunerno tunertype"
2292  QStringList devs = CardUtil::ProbeVideoDevices("VBOX");
2293 
2294  QStringList::const_iterator it;
2295 
2296  for (it = devs.begin(); it != devs.end(); ++it)
2297  {
2298  QString dev = *it;
2299  QStringList devinfo = dev.split(" ");
2300  QString id = devinfo.at(0);
2301  QString ip = devinfo.at(1);
2302  QString tunerNo = devinfo.at(2);
2303  QString tunerType = devinfo.at(3);
2304 
2305  VBoxDevice tmpdevice;
2306  tmpdevice.deviceid = id;
2307  tmpdevice.desc = CardUtil::GetVBoxdesc(id, ip, tunerNo, tunerType);
2308  tmpdevice.cardip = ip;
2309  tmpdevice.inuse = false;
2310  tmpdevice.discovered = true;
2311  tmpdevice.tunerno = tunerNo;
2312  tmpdevice.tunertype = tunerType;
2313  tmpdevice.mythdeviceid = id + "-" + tunerNo + "-" + tunerType;
2314  devicelist[tmpdevice.mythdeviceid] = tmpdevice;
2315  }
2316 
2317  // Now find configured devices
2318 
2319  // returns "ip.ip.ip.ip-n-type" or deviceid-n-type values
2320  QStringList db = CardUtil::GetVideoDevices("VBOX");
2321 
2322  for (it = db.begin(); it != db.end(); ++it)
2323  {
2324  QMap<QString, VBoxDevice>::iterator dit;
2325  dit = devicelist.find(*it);
2326 
2327  if (dit != devicelist.end())
2328  (*dit).inuse = true;
2329  }
2330 }
2331 
2333 {
2334  parent.reload(); // ensure card id is valid
2335 
2336  VBoxExtra acw(*this);
2337  acw.exec();
2338 }
2339 
2340 // -----------------------
2341 // Ceton Configuration
2342 // -----------------------
2343 
2344 CetonSetting::CetonSetting(const char* label, const char* helptext)
2345 {
2346  setLabel(QObject::tr(label));
2347  setHelpText(tr(helptext));
2348  connect(this, SIGNAL(valueChanged( const QString&)),
2349  this, SLOT( UpdateDevices(const QString&)));
2350 }
2351 
2352 void CetonSetting::UpdateDevices(const QString &v)
2353 {
2354  if (isEnabled())
2355  emit NewValue(v);
2356 }
2357 
2358 void CetonSetting::LoadValue(const QString &value)
2359 {
2360  setValue(value);
2361 }
2362 
2364  LabelSetting(this),
2365  CaptureCardDBStorage(this, parent, "videodevice"),
2366  _ip(), _card(), _tuner(), _parent(parent)
2367 {
2368  setLabel(tr("Device ID"));
2369  setHelpText(tr("Device ID of Ceton device"));
2370 }
2371 
2372 void CetonDeviceID::SetIP(const QString &ip)
2373 {
2374  QString regexp = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){4}$";
2375  if (QRegExp(regexp).exactMatch(ip + "."))
2376  {
2377  _ip = ip;
2378  setValue(QString("%1-RTP.%3").arg(_ip).arg(_tuner));
2379  }
2380 }
2381 
2382 void CetonDeviceID::SetTuner(const QString &tuner)
2383 {
2384  if (QRegExp("^\\d$").exactMatch(tuner))
2385  {
2386  _tuner = tuner;
2387  setValue(QString("%1-RTP.%2").arg(_ip).arg(_tuner));
2388  }
2389 }
2390 
2392 {
2394  UpdateValues();
2395 }
2396 
2398 {
2399  QRegExp newstyle("^([0-9.]+)-(\\d|RTP)\\.(\\d)$");
2400  if (newstyle.exactMatch(getValue()))
2401  {
2402  emit LoadedIP(newstyle.cap(1));
2403  emit LoadedTuner(newstyle.cap(3));
2404  }
2405 }
2406 
2409  parent(a_parent)
2410 {
2411  setUseLabel(false);
2412 
2413  deviceid = new CetonDeviceID(parent);
2414  desc = new TransLabelSetting();
2415  desc->setLabel(tr("Description"));
2416  ip = new CetonSetting(
2417  "IP Address",
2418  "IP Address of the Ceton device (192.168.200.1 by default)");
2419  tuner = new CetonSetting(
2420  "Tuner",
2421  "Number of the tuner on the Ceton device (first tuner is number 0)");
2422 
2423  addChild(ip);
2424  addChild(tuner);
2425  addChild(deviceid);
2426  addChild(desc);
2427 
2428  connect(ip, SIGNAL(NewValue(const QString&)),
2429  deviceid, SLOT( SetIP(const QString&)));
2430  connect(tuner, SIGNAL(NewValue(const QString&)),
2431  deviceid, SLOT( SetTuner(const QString&)));
2432 
2433  connect(deviceid, SIGNAL(LoadedIP(const QString&)),
2434  ip, SLOT( LoadValue(const QString&)));
2435  connect(deviceid, SIGNAL(LoadedTuner(const QString&)),
2436  tuner, SLOT( LoadValue(const QString&)));
2437 };
2438 
2441  parent(a_parent),
2442  cardinfo(new TransLabelSetting()), vbidev(new VBIDevice(parent))
2443 {
2444  QString drv = "(?!ivtv|hdpvr|(saa7164(.*))).*";
2445  VideoDevice *device = new VideoDevice(parent, 0, 15, QString::null, drv);
2447  new HorizontalConfigurationGroup(false, false, true, true);
2448 
2449  audgrp->addChild(new AudioRateLimit(parent));
2450  audgrp->addChild(new SkipBtAudio(parent));
2451 
2452  addChild(device);
2453  cardinfo->setLabel(tr("Probed info"));
2454  addChild(cardinfo);
2455 
2456  addChild(vbidev);
2457  addChild(new AudioDevice(parent));
2458  addChild(audgrp);
2459 
2460  connect(device, SIGNAL(valueChanged(const QString&)),
2461  this, SLOT( probeCard( const QString&)));
2462 
2463  probeCard(device->getValue());
2464 };
2465 
2466 void V4LConfigurationGroup::probeCard(const QString &device)
2467 {
2468  QString cn = tr("Failed to open"), ci = cn, dn = QString::null;
2469 
2470  QByteArray adevice = device.toLatin1();
2471  int videofd = open(adevice.constData(), O_RDWR);
2472  if (videofd >= 0)
2473  {
2474  if (!CardUtil::GetV4LInfo(videofd, cn, dn))
2475  ci = cn = tr("Failed to probe");
2476  else if (!dn.isEmpty())
2477  ci = cn + " [" + dn + "]";
2478  close(videofd);
2479  }
2480 
2481  cardinfo->setValue(ci);
2482  vbidev->setFilter(cn, dn);
2483 }
2484 
2487  parent(a_parent),
2488  device(NULL), vbidevice(NULL),
2490 {
2491  QString drv = "ivtv|(saa7164(.*))";
2492  device = new VideoDevice(parent, 0, 15, QString::null, drv);
2493  vbidevice = new VBIDevice(parent);
2494  vbidevice->setVisible(false);
2495 
2496  cardinfo->setLabel(tr("Probed info"));
2497 
2498  addChild(device);
2500  addChild(cardinfo);
2501  addChild(new ChannelTimeout(parent, 12000, 2000));
2502 
2503  connect(device, SIGNAL(valueChanged(const QString&)),
2504  this, SLOT( probeCard( const QString&)));
2505 
2507 }
2508 
2510 {
2511  QString cn = tr("Failed to open"), ci = cn, dn = QString::null;
2512 
2513  QByteArray adevice = device.toLatin1();
2514  int videofd = open(adevice.constData(), O_RDWR);
2515  if (videofd >= 0)
2516  {
2517  if (!CardUtil::GetV4LInfo(videofd, cn, dn))
2518  ci = cn = tr("Failed to probe");
2519  else if (!dn.isEmpty())
2520  ci = cn + " [" + dn + "]";
2521  close(videofd);
2522  }
2523 
2524  cardinfo->setValue(ci);
2525  vbidevice->setVisible(dn!="ivtv");
2526  vbidevice->setFilter(cn, dn);
2527 }
2528 
2531  parent(a_parent),
2532  info(new TransLabelSetting()), size(new TransLabelSetting())
2533 {
2534  FileDevice *device = new FileDevice(parent);
2535  device->setHelpText(tr("A local MPEG file used to simulate a recording."
2536  " Must be entered as file:/path/movie.mpg"));
2537  device->addSelection("file:/");
2538  addChild(device);
2539 
2542 
2543  info->setLabel(tr("File info"));
2544  addChild(info);
2545 
2546  size->setLabel(tr("File size"));
2547  addChild(size);
2548 
2549  connect(device, SIGNAL(valueChanged(const QString&)),
2550  this, SLOT( probeCard( const QString&)));
2551 
2552  probeCard(device->getValue());
2553 }
2554 
2555 void DemoConfigurationGroup::probeCard(const QString &device)
2556 {
2557  if (!device.startsWith("file:", Qt::CaseInsensitive))
2558  {
2559  info->setValue("");
2560  size->setValue("");
2561  return;
2562  }
2563 
2564 
2565  QString ci, cs;
2566  QFileInfo fileInfo(device.mid(5));
2567  if (fileInfo.exists())
2568  {
2569  if (fileInfo.isReadable() && (fileInfo.isFile()))
2570  {
2571  ci = HTTPRequest::TestMimeType(fileInfo.absoluteFilePath());
2572  cs = tr("%1 MB").arg(fileInfo.size() / 1024 / 1024);
2573  }
2574  else
2575  ci = tr("File not readable");
2576  }
2577  else
2578  {
2579  ci = tr("File does not exist");
2580  }
2581 
2582  info->setValue(ci);
2583  size->setValue(cs);
2584 }
2585 
2586 #if !defined( USING_MINGW ) && !defined( _MSC_VER )
2589  parent(a_parent),
2590  info(new TransLabelSetting())
2591 {
2592  FileDevice *device = new FileDevice(parent);
2593  device->setHelpText(tr("A 'black box' application controlled via "
2594  "stdin, status on stderr and TransportStream "
2595  "read from stdout"));
2596  addChild(device);
2597 
2598  info->setLabel(tr("File info"));
2599  addChild(info);
2600 
2601  connect(device, SIGNAL(valueChanged(const QString&)),
2602  this, SLOT( probeApp( const QString&)));
2603 
2604  probeApp(device->getValue());
2605 }
2606 
2607 void ExternalConfigurationGroup::probeApp(const QString & path)
2608 {
2609  int idx1 = path.toLower().startsWith("file:") ? 5 : 0;
2610  int idx2 = path.indexOf(' ', idx1);
2611 
2612  QString ci, cs;
2613  QFileInfo fileInfo(path.mid(idx1, idx2 - idx1));
2614 
2615  if (fileInfo.exists())
2616  {
2617  ci = tr("'%1' is valid.").arg(fileInfo.absoluteFilePath());
2618  if (!fileInfo.isReadable() || !fileInfo.isFile())
2619  ci = tr("'%1' is not readable.").arg(fileInfo.absoluteFilePath());
2620  if (!fileInfo.isExecutable())
2621  ci = tr("'%1' is not executable.").arg(fileInfo.absoluteFilePath());
2622  }
2623  else
2624  {
2625  ci = tr("'%1' does not exist.").arg(fileInfo.absoluteFilePath());
2626  }
2627 
2628  info->setValue(ci);
2629 }
2630 #endif // !defined( USING_MINGW ) && !defined( _MSC_VER )
2631 
2634  parent(a_parent), cardinfo(new TransLabelSetting()),
2635  audioinput(new TunerCardAudioInput(parent, QString::null, "HDPVR")),
2636  vbidevice(NULL)
2637 {
2638  VideoDevice *device =
2639  new VideoDevice(parent, 0, 15, QString::null, "hdpvr");
2640 
2641  cardinfo->setLabel(tr("Probed info"));
2642 
2643  addChild(device);
2646  addChild(cardinfo);
2648  addChild(new ChannelTimeout(parent, 15000, 2000));
2649 
2650  connect(device, SIGNAL(valueChanged(const QString&)),
2651  this, SLOT( probeCard( const QString&)));
2652 
2653  probeCard(device->getValue());
2654 }
2655 
2656 void HDPVRConfigurationGroup::probeCard(const QString &device)
2657 {
2658  QString cn = tr("Failed to open"), ci = cn, dn = QString::null;
2659 
2660  int videofd = open(device.toLocal8Bit().constData(), O_RDWR);
2661  if (videofd >= 0)
2662  {
2663  if (!CardUtil::GetV4LInfo(videofd, cn, dn))
2664  ci = cn = tr("Failed to probe");
2665  else if (!dn.isEmpty())
2666  ci = cn + " [" + dn + "]";
2667  close(videofd);
2668  }
2669 
2670  cardinfo->setValue(ci);
2671  audioinput->fillSelections(device);
2672 }
2673 
2676  m_parent(parent),
2677  m_cardinfo(new TransLabelSetting())
2678 {
2679  setLabel(QObject::tr("V4L2 encoder devices (multirec capable)"));
2680  VideoDevice *device = new VideoDevice(m_parent, 0, 15);
2681 
2682  addChild(device);
2683  m_cardinfo->setLabel(tr("Probed info"));
2685 
2686  // Choose children to show based on which device is active
2687  setTrigger(device);
2688  // Only save settings for 'this' device.
2689  setSaveAll(false);
2690 
2691  connect(device, SIGNAL(valueChanged(const QString&)),
2692  this, SLOT( probeCard( const QString&)));
2693 
2694  probeCard(device->getValue());
2695 }
2696 
2697 void V4L2encGroup::triggerChanged(const QString& dev_path)
2698 {
2699  probeCard(dev_path);
2701 }
2702 
2703 void V4L2encGroup::probeCard(const QString &device_name)
2704 {
2705 #ifdef USING_V4L2
2706  QString card_name = tr("Failed to open");
2707  QString card_info = card_name;
2708  V4L2util v4l2(device_name);
2709 
2710  if (!v4l2.IsOpen())
2711  {
2712  m_DriverName = tr("Failed to probe");
2713  return;
2714  }
2715  m_DriverName = v4l2.DriverName();
2716  card_name = v4l2.CardName();
2717 
2718  if (!m_DriverName.isEmpty())
2719  card_info = card_name + " [" + m_DriverName + "]";
2720 
2721  m_cardinfo->setValue(card_info);
2722 
2724  QMap<QString,Configurable*>::iterator it = triggerMap.find(m_DriverName);
2725  if (it == triggerMap.end())
2726  {
2727  grp = new VerticalConfigurationGroup(false);
2728 
2729  TunerCardAudioInput* audioinput =
2730  new TunerCardAudioInput(m_parent, QString::null, "V4L2");
2731  audioinput->fillSelections(device_name);
2732  if (audioinput->size() > 1)
2733  {
2734  audioinput->setName("AudioInput");
2735  grp->addChild(audioinput);
2736  }
2737  else
2738  delete audioinput;
2739 
2740  if (v4l2.HasSlicedVBI())
2741  {
2742  VBIDevice* vbidev = new VBIDevice(m_parent);
2743  vbidev->setFilter(card_name, m_DriverName);
2744  if (vbidev->size() > 0)
2745  {
2746  vbidev->setName("VBIDevice");
2747  grp->addChild(vbidev);
2748  }
2749  else
2750  delete vbidev;
2751  }
2752 
2753  grp->addChild(new EmptyVBIDevice(m_parent));
2754  grp->addChild(new ChannelTimeout(m_parent, 15000, 2000));
2755 
2756  addTarget(m_DriverName, grp);
2757  }
2758 #endif // USING_V4L2
2759 }
2760 
2763 {
2764  setLabel(QObject::tr("Capture Card Setup"));
2765 
2766  CardType* cardtype = new CardType(parent);
2767  addChild(cardtype);
2768 
2769  setTrigger(cardtype);
2770  setSaveAll(false);
2771 
2772 #ifdef USING_DVB
2773  addTarget("DVB", new DVBConfigurationGroup(parent));
2774 #endif // USING_DVB
2775 
2776 #ifdef USING_V4L2
2777 # ifdef USING_HDPVR
2778  addTarget("HDPVR", new HDPVRConfigurationGroup(parent));
2779 # endif // USING_HDPVR
2780 #endif // USING_V4L2
2781 
2782 #ifdef USING_HDHOMERUN
2783  addTarget("HDHOMERUN", new HDHomeRunConfigurationGroup(parent));
2784 #endif // USING_HDHOMERUN
2785 
2786 #ifdef USING_VBOX
2787  addTarget("VBOX", new VBoxConfigurationGroup(parent));
2788 #endif // USING_VBOX
2789 
2790 #ifdef USING_FIREWIRE
2791  addTarget("FIREWIRE", new FirewireConfigurationGroup(parent));
2792 #endif // USING_FIREWIRE
2793 
2794 #ifdef USING_CETON
2795  addTarget("CETON", new CetonConfigurationGroup(parent));
2796 #endif // USING_CETON
2797 
2798 #ifdef USING_IPTV
2799  addTarget("FREEBOX", new IPTVConfigurationGroup(parent));
2800 #endif // USING_IPTV
2801 
2802 #ifdef USING_V4L2
2803  addTarget("V4L2ENC", new V4L2encGroup(parent));
2804  addTarget("V4L", new V4LConfigurationGroup(parent));
2805 # ifdef USING_IVTV
2806  addTarget("MPEG", new MPEGConfigurationGroup(parent));
2807 # endif // USING_IVTV
2808 #endif // USING_V4L2
2809 
2810 #ifdef USING_ASI
2811  addTarget("ASI", new ASIConfigurationGroup(parent));
2812 #endif // USING_ASI
2813 
2814  // for testing without any actual tuner hardware:
2815  addTarget("IMPORT", new ImportConfigurationGroup(parent));
2816  addTarget("DEMO", new DemoConfigurationGroup(parent));
2817 #if !defined( USING_MINGW ) && !defined( _MSC_VER )
2818  addTarget("EXTERNAL", new ExternalConfigurationGroup(parent));
2819 #endif
2820 }
2821 
2823 {
2824  QString own = (value == "MJPEG" || value == "GO7007") ? "V4L" : value;
2826 }
2827 
2828 CaptureCard::CaptureCard(bool use_card_group)
2829  : id(new ID)
2830 {
2831  addChild(id);
2832  if (use_card_group)
2833  addChild(new CaptureCardGroup(*this));
2834  addChild(new Hostname(*this));
2835 }
2836 
2837 QString CaptureCard::GetRawCardType(void) const
2838 {
2839  int cardid = getCardID();
2840  if (cardid <= 0)
2841  return QString::null;
2842  return CardUtil::GetRawInputType(cardid);
2843 }
2844 
2846 {
2847  MSqlQuery query(MSqlQuery::InitCon());
2848  QString qstr =
2849  "SELECT cardid, videodevice, cardtype "
2850  "FROM capturecard "
2851  "WHERE hostname = :HOSTNAME AND parentid = 0 "
2852  "ORDER BY cardid";
2853 
2854  query.prepare(qstr);
2855  query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
2856 
2857  if (!query.exec())
2858  {
2859  MythDB::DBError("CaptureCard::fillSelections", query);
2860  return;
2861  }
2862 
2863  while (query.next())
2864  {
2865  uint cardid = query.value(0).toUInt();
2866  QString videodevice = query.value(1).toString();
2867  QString cardtype = query.value(2).toString();
2868  QString label = CardUtil::GetDeviceLabel(cardtype, videodevice);
2869  setting->addSelection(label, QString::number(cardid));
2870  }
2871 }
2872 
2873 void CaptureCard::loadByID(int cardid)
2874 {
2875  id->setValue(cardid);
2876  Load();
2877 }
2878 
2880 {
2881  uint init_cardid = getCardID();
2882  QString init_type = CardUtil::GetRawInputType(init_cardid);
2883  QString init_dev = CardUtil::GetVideoDevice(init_cardid);
2884  QString init_input = CardUtil::GetInputName(init_cardid);
2885 
2887 
2889 
2891 
2892  uint cardid = getCardID();
2893  QString type = CardUtil::GetRawInputType(cardid);
2894  QString dev = CardUtil::GetVideoDevice(cardid);
2895 
2896  if (dev != init_dev)
2897  {
2898  if (!init_dev.isEmpty())
2899  {
2900  uint init_groupid = CardUtil::GetDeviceInputGroup(init_cardid);
2901  CardUtil::UnlinkInputGroup(init_cardid, init_groupid);
2902  }
2903  if (!dev.isEmpty())
2904  {
2905  uint groupid =
2906  CardUtil::CreateDeviceInputGroup(cardid, type,
2907  gCoreContext->GetHostName(), dev);
2908  CardUtil::LinkInputGroup(cardid, groupid);
2909  CardUtil::UnlinkInputGroup(0, groupid);
2910  }
2911  }
2912 
2913  // Handle any cloning we may need to do
2915  {
2916  vector<uint> clones = CardUtil::GetChildInputIDs(cardid);
2917  for (uint i = 0; i < clones.size(); i++)
2918  CardUtil::CloneCard(cardid, clones[i]);
2919  }
2920 }
2921 
2923 {
2924  if (getCardID() == 0)
2925  {
2926  Save();
2927  Load();
2928  }
2929 }
2930 
2932  ComboBoxSetting(this),
2933  CaptureCardDBStorage(this, parent, "cardtype")
2934 {
2935  setLabel(QObject::tr("Card type"));
2936  setHelpText(QObject::tr("Change the cardtype to the appropriate type for "
2937  "the capture card you are configuring."));
2938  fillSelections(this);
2939 }
2940 
2942 {
2943 #ifdef USING_DVB
2944  setting->addSelection(
2945  QObject::tr("DVB-T/S/C, ATSC or ISDB-T tuner card"), "DVB");
2946 #endif // USING_DVB
2947 
2948 #ifdef USING_V4L2
2949  setting->addSelection(
2950  QObject::tr("V4L2 encoder"), "V4L2ENC");
2951 #ifdef USING_HDPVR
2952  setting->addSelection(
2953  QObject::tr("HD-PVR H.264 encoder"), "HDPVR");
2954 # endif // USING_HDPVR
2955 #endif // USING_V4L2
2956 
2957 #ifdef USING_HDHOMERUN
2958  setting->addSelection(
2959  QObject::tr("HDHomeRun networked tuner"), "HDHOMERUN");
2960 #endif // USING_HDHOMERUN
2961 
2962 #ifdef USING_VBOX
2963  setting->addSelection(
2964  QObject::tr("V@Box TV Gateway networked tuner"), "VBOX");
2965 #endif // USING_VBOX
2966 
2967 #ifdef USING_FIREWIRE
2968  setting->addSelection(
2969  QObject::tr("FireWire cable box"), "FIREWIRE");
2970 #endif // USING_FIREWIRE
2971 
2972 #ifdef USING_CETON
2973  setting->addSelection(
2974  QObject::tr("Ceton Cablecard tuner"), "CETON");
2975 #endif // USING_CETON
2976 
2977 #ifdef USING_IPTV
2978  setting->addSelection(QObject::tr("IPTV recorder"), "FREEBOX");
2979 #endif // USING_IPTV
2980 
2981 #ifdef USING_V4L2
2982 # ifdef USING_IVTV
2983  setting->addSelection(
2984  QObject::tr("Analog to MPEG-2 encoder card (PVR-150/250/350, etc)"), "MPEG");
2985 # endif // USING_IVTV
2986  setting->addSelection(
2987  QObject::tr("Analog to MJPEG encoder card (Matrox G200, DC10, etc)"), "MJPEG");
2988  setting->addSelection(
2989  QObject::tr("Analog to MPEG-4 encoder (Plextor ConvertX USB, etc)"),
2990  "GO7007");
2991  setting->addSelection(
2992  QObject::tr("Analog capture card"), "V4L");
2993 #endif // USING_V4L2
2994 
2995 #ifdef USING_ASI
2996  setting->addSelection(QObject::tr("DVEO ASI recorder"), "ASI");
2997 #endif
2998 
2999  setting->addSelection(QObject::tr("Import test recorder"), "IMPORT");
3000  setting->addSelection(QObject::tr("Demo test recorder"), "DEMO");
3001 #if !defined( USING_MINGW ) && !defined( _MSC_VER )
3002  setting->addSelection(QObject::tr("External (black box) recorder"),
3003  "EXTERNAL");
3004 #endif
3005 }
3006 
3008 {
3009  public:
3010  InputName(const CardInput &parent) :
3011  ComboBoxSetting(this), CardInputDBStorage(this, parent, "inputname")
3012  {
3013  setLabel(QObject::tr("Input name"));
3014  };
3015 
3016  virtual void Load(void)
3017  {
3018  fillSelections();
3020  };
3021 
3023  clearSelections();
3024  addSelection(QObject::tr("(None)"), "None");
3025  uint cardid = getInputID();
3026  QString type = CardUtil::GetRawInputType(cardid);
3027  QString device = CardUtil::GetVideoDevice(cardid);
3028  QStringList inputs;
3029  CardUtil::GetDeviceInputNames(cardid, device, type, inputs);
3030  while (!inputs.isEmpty())
3031  {
3032  addSelection(inputs.front());
3033  inputs.pop_front();
3034  }
3035  };
3036 };
3037 
3039 {
3040  public:
3041  InputDisplayName(const CardInput &parent) :
3042  LineEditSetting(this),
3043  CardInputDBStorage(this, parent, "displayname")
3044  {
3045  setLabel(QObject::tr("Display name (optional)"));
3046  setHelpText(QObject::tr(
3047  "This name is displayed on screen when Live TV begins "
3048  "and when changing the selected input or card. If you "
3049  "use this, make sure the information is unique for "
3050  "each input."));
3051  };
3052 };
3053 
3055 {
3056  public:
3057  SourceID(const CardInput &parent) :
3058  ComboBoxSetting(this), CardInputDBStorage(this, parent, "sourceid")
3059  {
3060  setLabel(QObject::tr("Video source"));
3061  addSelection(QObject::tr("(None)"), "0");
3062  };
3063 
3064  virtual void Load(void)
3065  {
3066  fillSelections();
3068  };
3069 
3071  clearSelections();
3072  addSelection(QObject::tr("(None)"), "0");
3074  };
3075 };
3076 
3078 {
3079  public:
3080  InputGroup(const CardInput &parent, uint group_num) :
3081  TransComboBoxSetting(false), cardinput(parent),
3082  groupnum(group_num), groupid(0)
3083  {
3084  setLabel(QObject::tr("Input group") +
3085  QString(" %1").arg(groupnum + 1));
3086  setHelpText(QObject::tr(
3087  "Leave as 'Generic' unless this input is shared with "
3088  "another device. Only one of the inputs in an input "
3089  "group will be allowed to record at any given time."));
3090  }
3091 
3092  virtual void Load(void);
3093 
3094  virtual void Save(void)
3095  {
3096  uint inputid = cardinput.getInputID();
3097  uint new_groupid = getValue().toUInt();
3098 
3099  if (groupid)
3100  CardUtil::UnlinkInputGroup(inputid, groupid);
3101 
3102  if (new_groupid)
3103  {
3104  if (CardUtil::UnlinkInputGroup(inputid, new_groupid))
3105  CardUtil::LinkInputGroup(inputid, new_groupid);
3106  }
3107  }
3108 
3109  virtual void Save(QString /*destination*/) { Save(); }
3110 
3111  private:
3115 };
3116 
3118 {
3119 #if 0
3120  LOG(VB_GENERAL, LOG_DEBUG, QString("InputGroup::Load() %1 %2")
3121  .arg(groupnum).arg(cardinput.getInputID()));
3122 #endif
3123 
3124  uint inputid = cardinput.getInputID();
3125  QMap<uint, uint> grpcnt;
3126  vector<QString> names;
3127  vector<uint> grpid;
3128  vector<uint> selected_groupids;
3129 
3130  names.push_back(QObject::tr("Generic"));
3131  grpid.push_back(0);
3132  grpcnt[0]++;
3133 
3134  MSqlQuery query(MSqlQuery::InitCon());
3135  query.prepare(
3136  "SELECT cardinputid, inputgroupid, inputgroupname "
3137  "FROM inputgroup "
3138  "WHERE inputgroupname LIKE 'user:%' "
3139  "ORDER BY inputgroupid, cardinputid, inputgroupname");
3140 
3141  if (!query.exec())
3142  {
3143  MythDB::DBError("InputGroup::Load()", query);
3144  }
3145  else
3146  {
3147  while (query.next())
3148  {
3149  uint groupid = query.value(1).toUInt();
3150  if (inputid && (query.value(0).toUInt() == inputid))
3151  selected_groupids.push_back(groupid);
3152 
3153  grpcnt[groupid]++;
3154 
3155  if (grpcnt[groupid] == 1)
3156  {
3157  names.push_back(query.value(2).toString().mid(5, -1));
3158  grpid.push_back(groupid);
3159  }
3160  }
3161  }
3162 
3163  // makes sure we select something
3164  groupid = 0;
3165  if (groupnum < selected_groupids.size())
3166  groupid = selected_groupids[groupnum];
3167 
3168 #if 0
3169  LOG(VB_GENERAL, LOG_DEBUG, QString("Group num: %1 id: %2")
3170  .arg(groupnum).arg(groupid));
3171  {
3172  QString msg;
3173  for (uint i = 0; i < selected_groupids.size(); i++)
3174  msg += QString("%1 ").arg(selected_groupids[i]);
3175  LOG(VB_GENERAL, LOG_DEBUG, msg);
3176  }
3177 #endif
3178 
3179  // add selections to combobox
3180  clearSelections();
3181  uint index = 0;
3182  for (uint i = 0; i < names.size(); i++)
3183  {
3184  bool sel = (groupid == grpid[i]);
3185  index = (sel) ? i : index;
3186 
3187 #if 0
3188  LOG(VB_GENERAL, LOG_DEBUG, QString("grpid %1, name '%2', i %3, s %4")
3189  .arg(grpid[i]).arg(names[i]) .arg(index).arg(sel ? "T" : "F"));
3190 #endif
3191 
3192  addSelection(names[i], QString::number(grpid[i]), sel);
3193  }
3194 
3195 #if 0
3196  LOG(VB_GENERAL, LOG_DEBUG, QString("Group index: %1").arg(index));
3197 #endif
3198 
3199  if (!names.empty())
3200  setValue(index);
3201 }
3202 
3204 {
3205  public:
3206  QuickTune(const CardInput &parent) :
3207  ComboBoxSetting(this), CardInputDBStorage(this, parent, "quicktune")
3208  {
3209  setLabel(QObject::tr("Use quick tuning"));
3210  addSelection(QObject::tr("Never"), "0", true);
3211  addSelection(QObject::tr("Live TV only"), "1", false);
3212  addSelection(QObject::tr("Always"), "2", false);
3213  setHelpText(QObject::tr(
3214  "If enabled, MythTV will tune using only the "
3215  "MPEG program number. The program numbers "
3216  "change more often than DVB or ATSC tuning "
3217  "parameters, so this is slightly less reliable. "
3218  "This will also inhibit EIT gathering during "
3219  "Live TV and recording."));
3220  };
3221 };
3222 
3224  public LineEditSetting, public CardInputDBStorage
3225 {
3226  public:
3228  LineEditSetting(this),
3229  CardInputDBStorage(this, parent, "externalcommand")
3230  {
3231  setLabel(QObject::tr("External channel change command"));
3232  setValue("");
3233  setHelpText(QObject::tr("If specified, this command will be run to "
3234  "change the channel for inputs which have an external "
3235  "tuner device such as a cable box. The first argument "
3236  "will be the channel number."));
3237  };
3238 };
3239 
3241 {
3242  public:
3243  PresetTuner(const CardInput &parent) :
3244  LineEditSetting(this),
3245  CardInputDBStorage(this, parent, "tunechan")
3246  {
3247  setLabel(QObject::tr("Preset tuner to channel"));
3248  setValue("");
3249  setHelpText(QObject::tr("Leave this blank unless you have an external "
3250  "tuner that is connected to the tuner input of your card. "
3251  "If so, you will need to specify the preset channel for "
3252  "the signal (normally 3 or 4)."));
3253  };
3254 };
3255 
3256 void StartingChannel::SetSourceID(const QString &sourceid)
3257 {
3258  clearSelections();
3259  if (sourceid.isEmpty() || !sourceid.toUInt())
3260  return;
3261 
3262  // Get the existing starting channel
3263  QString startChan = CardUtil::GetStartingChannel(getInputID());
3264 
3265  ChannelInfoList channels = ChannelUtil::GetAllChannels(sourceid.toUInt());
3266 
3267  if (channels.empty())
3268  {
3269  addSelection(tr("Please add channels to this source"),
3270  startChan.isEmpty() ? "0" : startChan);
3271  return;
3272  }
3273 
3274  // If there are channels sort them, then add theme
3275  // (selecting the old start channel if it is there).
3276  QString order = gCoreContext->GetSetting("ChannelOrdering", "channum");
3277  ChannelUtil::SortChannels(channels, order);
3278  bool has_visible = false;
3279  for (uint i = 0; i < channels.size() && !has_visible; i++)
3280  has_visible |= channels[i].visible;
3281 
3282  for (uint i = 0; i < channels.size(); i++)
3283  {
3284  const QString channum = channels[i].channum;
3285  bool sel = channum == startChan;
3286  if (!has_visible || channels[i].visible || sel)
3287  {
3288  addSelection(channum, channum, sel);
3289  }
3290  }
3291 }
3292 
3294 {
3295  public:
3296  InputPriority(const CardInput &parent) :
3297  SpinBoxSetting(this, -99, 99, 1),
3298  CardInputDBStorage(this, parent, "recpriority")
3299  {
3300  setLabel(QObject::tr("Input priority"));
3301  setValue(0);
3302  setHelpText(QObject::tr("If the input priority is not equal for "
3303  "all inputs, the scheduler may choose to record a show "
3304  "at a later time so that it can record on an input with "
3305  "a higher value."));
3306  };
3307 };
3308 
3310 {
3311  public:
3312  ScheduleOrder(const CardInput &parent, int _value) :
3313  SpinBoxSetting(this, 0, 99, 1),
3314  CardInputDBStorage(this, parent, "schedorder")
3315  {
3316  setLabel(QObject::tr("Schedule order"));
3317  setValue(_value);
3318  setHelpText(QObject::tr("If priorities and other factors are equal "
3319  "the scheduler will choose the available "
3320  "input with the lowest, non-zero value. "
3321  "Setting this value to zero will make the "
3322  "input unavailable to the scheduler."));
3323  };
3324 };
3325 
3327 {
3328  public:
3329  LiveTVOrder(const CardInput &parent, int _value) :
3330  SpinBoxSetting(this, 0, 99, 1),
3331  CardInputDBStorage(this, parent, "livetvorder")
3332  {
3333  setLabel(QObject::tr("Live TV order"));
3334  setValue(_value);
3335  setHelpText(QObject::tr("When entering Live TV, the available, local "
3336  "input with the lowest, non-zero value will "
3337  "be used. If no local inputs are available, "
3338  "the available, remote input with the lowest, "
3339  "non-zero value will be used. "
3340  "Setting this value to zero will make the "
3341  "input unavailable to live TV."));
3342  };
3343 };
3344 
3346 {
3347  public:
3348  DishNetEIT(const CardInput &parent) :
3349  CheckBoxSetting(this),
3350  CardInputDBStorage(this, parent, "dishnet_eit")
3351  {
3352  setLabel(QObject::tr("Use DishNet long-term EIT data"));
3353  setValue(false);
3354  setHelpText(
3355  QObject::tr(
3356  "If you point your satellite dish toward DishNet's birds, "
3357  "you may wish to enable this feature. For best results, "
3358  "enable general EIT collection as well."));
3359  };
3360 };
3361 
3362 CardInput::CardInput(const QString & cardtype, const QString & device,
3363  bool isNewInput, int _cardid) :
3364  id(new ID()),
3365  inputname(new InputName(*this)),
3366  sourceid(new SourceID(*this)),
3367  startchan(new StartingChannel(*this)),
3368  scan(new TransButtonSetting()),
3369  srcfetch(new TransButtonSetting()),
3370  externalInputSettings(new DiSEqCDevSettings()),
3371  inputgrp0(new InputGroup(*this, 0)),
3372  inputgrp1(new InputGroup(*this, 1)),
3373  instancecount(NULL),
3374  schedgroup(NULL)
3375 {
3376  addChild(id);
3377 
3379  {
3381  _cardid, isNewInput));
3382  }
3383 
3384  ConfigurationGroup *basic =
3385  new VerticalConfigurationGroup(false, false, true, true);
3386 
3387  basic->setLabel(QObject::tr("Connect source to input"));
3388 
3389  basic->addChild(inputname);
3390  basic->addChild(new InputDisplayName(*this));
3391  basic->addChild(sourceid);
3392 
3393  if (CardUtil::IsEncoder(cardtype) || CardUtil::IsUnscanable(cardtype))
3394  {
3395  basic->addChild(new ExternalChannelCommand(*this));
3396  if (CardUtil::HasTuner(cardtype, device))
3397  basic->addChild(new PresetTuner(*this));
3398  }
3399  else
3400  {
3401  ConfigurationGroup *chgroup =
3402  new HorizontalConfigurationGroup(false, false, true, true);
3403  chgroup->addChild(new QuickTune(*this));
3404  if ("DVB" == cardtype)
3405  chgroup->addChild(new DishNetEIT(*this));
3406  basic->addChild(chgroup);
3407  }
3408 
3409  scan->setLabel(tr("Scan for channels"));
3410  scan->setHelpText(
3411  tr("Use channel scanner to find channels for this input."));
3412 
3413  srcfetch->setLabel(tr("Fetch channels from listings source"));
3415  tr("This uses the listings data source to "
3416  "provide the channels for this input.") + " " +
3417  tr("This can take a long time to run."));
3418 
3419  ConfigurationGroup *sgrp =
3420  new HorizontalConfigurationGroup(false, false, true, true);
3421  sgrp->addChild(scan);
3422  sgrp->addChild(srcfetch);
3423  basic->addChild(sgrp);
3424 
3425  basic->addChild(startchan);
3426 
3427  addChild(basic);
3428 
3429  ConfigurationGroup *interact =
3430  new VerticalConfigurationGroup(false, false, true, true);
3431 
3432  interact->setLabel(QObject::tr("Interactions between inputs"));
3433  if (CardUtil::IsTunerSharingCapable(cardtype))
3434  {
3436  interact->addChild(instancecount);
3437  schedgroup = new SchedGroup(*this);
3438  interact->addChild(schedgroup);
3439  }
3440  interact->addChild(new InputPriority(*this));
3441  interact->addChild(new ScheduleOrder(*this, _cardid));
3442  interact->addChild(new LiveTVOrder(*this, _cardid));
3443 
3444  TransButtonSetting *ingrpbtn = new TransButtonSetting("newgroup");
3445  ingrpbtn->setLabel(QObject::tr("Create a New Input Group"));
3446  ingrpbtn->setHelpText(
3447  QObject::tr("Input groups are only needed when two or more cards "
3448  "share the same resource such as a FireWire card and "
3449  "an analog card input controlling the same set top box."));
3450  interact->addChild(ingrpbtn);
3451  interact->addChild(inputgrp0);
3452  interact->addChild(inputgrp1);
3453 
3454  addChild(interact);
3455 
3456  setObjectName("CardInput");
3457  SetSourceID("-1");
3458 
3459  connect(scan, SIGNAL(pressed()), SLOT(channelScanner()));
3460  connect(srcfetch, SIGNAL(pressed()), SLOT(sourceFetch()));
3461  connect(sourceid, SIGNAL(valueChanged(const QString&)),
3462  startchan,SLOT( SetSourceID (const QString&)));
3463  connect(sourceid, SIGNAL(valueChanged(const QString&)),
3464  this, SLOT( SetSourceID (const QString&)));
3465  connect(ingrpbtn, SIGNAL(pressed(QString)),
3466  this, SLOT( CreateNewInputGroup()));
3467  if (schedgroup)
3468  connect(instancecount, SIGNAL(valueChanged(int)),
3469  this, SLOT(UpdateSchedGroup(int)));
3470 }
3471 
3473 {
3475  {
3476  delete externalInputSettings;
3477  externalInputSettings = NULL;
3478  }
3479 }
3480 
3481 void CardInput::SetSourceID(const QString &sourceid)
3482 {
3483  uint cid = id->getValue().toUInt();
3484  QString raw_card_type = CardUtil::GetRawInputType(cid);
3485  bool enable = (sourceid.toInt() > 0);
3486  scan->setEnabled(enable && !raw_card_type.isEmpty() &&
3487  !CardUtil::IsUnscanable(raw_card_type));
3488  srcfetch->setEnabled(enable);
3489 }
3490 
3492 {
3493  if (value <= 1)
3494  schedgroup->setValue(false);
3495  schedgroup->setEnabled(value > 1);
3496 }
3497 
3498 QString CardInput::getSourceName(void) const
3499 {
3500  return sourceid->getSelectionLabel();
3501 }
3502 
3504 {
3505  QString new_name = QString::null;
3506  QString tmp_name = QString::null;
3507 
3508  inputgrp0->Save();
3509  inputgrp1->Save();
3510 
3511  while (true)
3512  {
3513  tmp_name = "";
3515  GetMythMainWindow(), tr("Create Input Group"),
3516  tr("Enter new group name"), tmp_name);
3517 
3518  if (!ok)
3519  return;
3520 
3521  if (tmp_name.isEmpty())
3522  {
3524  GetMythMainWindow(), tr("Error"),
3525  tr("Sorry, this Input Group name cannot be blank."));
3526  continue;
3527  }
3528 
3529  new_name = QString("user:") + tmp_name;
3530 
3531  MSqlQuery query(MSqlQuery::InitCon());
3532  query.prepare(
3533  "SELECT inputgroupname "
3534  "FROM inputgroup "
3535  "WHERE inputgroupname = :GROUPNAME");
3536  query.bindValue(":GROUPNAME", new_name);
3537 
3538  if (!query.exec())
3539  {
3540  MythDB::DBError("CreateNewInputGroup 1", query);
3541  return;
3542  }
3543 
3544  if (query.next())
3545  {
3547  GetMythMainWindow(), tr("Error"),
3548  tr("Sorry, this Input Group name is already in use."));
3549  continue;
3550  }
3551 
3552  break;
3553  }
3554 
3555  uint inputgroupid = CardUtil::CreateInputGroup(new_name);
3556 
3557  inputgrp0->Load();
3558  inputgrp1->Load();
3559 
3560  if (!inputgrp0->getValue().toUInt())
3561  {
3563  inputgrp0->getValueIndex(QString::number(inputgroupid)));
3564  }
3565  else
3566  {
3568  inputgrp1->getValueIndex(QString::number(inputgroupid)));
3569  }
3570 }
3571 
3573 {
3574  uint srcid = sourceid->getValue().toUInt();
3575  uint crdid = id->getValue().toUInt();
3576  QString in = inputname->getValue();
3577 
3578 #ifdef USING_BACKEND
3579  uint num_channels_before = SourceUtil::GetChannelCount(srcid);
3580 
3581  Save(); // save info for scanner.
3582 
3583  QString cardtype = CardUtil::GetRawInputType(crdid);
3584  if (CardUtil::IsUnscanable(cardtype))
3585  {
3586  LOG(VB_GENERAL, LOG_ERR,
3587  QString("Sorry, %1 cards do not yet support scanning.")
3588  .arg(cardtype));
3589  return;
3590  }
3591 
3592  ScanWizard *scanwizard = new ScanWizard(srcid, crdid, in);
3593  scanwizard->exec(false, true);
3594  scanwizard->deleteLater();
3595 
3596  if (SourceUtil::GetChannelCount(srcid))
3597  startchan->SetSourceID(QString::number(srcid));
3598  if (num_channels_before)
3599  {
3600  startchan->Load();
3601  startchan->Save();
3602  }
3603 #else
3604  LOG(VB_GENERAL, LOG_ERR, "You must compile the backend "
3605  "to be able to scan for channels");
3606 #endif
3607 }
3608 
3610 {
3611  uint srcid = sourceid->getValue().toUInt();
3612  uint crdid = id->getValue().toUInt();
3613 
3614  uint num_channels_before = SourceUtil::GetChannelCount(srcid);
3615 
3616  if (crdid && srcid)
3617  {
3618  Save(); // save info for fetch..
3619 
3620  QString cardtype = CardUtil::GetRawInputType(crdid);
3621 
3622  if (!CardUtil::IsCableCardPresent(crdid, cardtype) &&
3623  !CardUtil::IsUnscanable(cardtype) &&
3624  !CardUtil::IsEncoder(cardtype) &&
3625  !num_channels_before)
3626  {
3627  LOG(VB_GENERAL, LOG_ERR, "Skipping channel fetch, you need to "
3628  "scan for channels first.");
3629  return;
3630  }
3631 
3632  SourceUtil::UpdateChannelsFromListings(srcid, cardtype);
3633  }
3634 
3635  if (SourceUtil::GetChannelCount(srcid))
3636  startchan->SetSourceID(QString::number(srcid));
3637  if (num_channels_before)
3638  {
3639  startchan->Load();
3640  startchan->Save();
3641  }
3642 }
3643 
3645 {
3646  QString cardinputidTag(":WHERECARDID");
3647 
3648  QString query("cardid = " + cardinputidTag);
3649 
3650  bindings.insert(cardinputidTag, m_parent.getInputID());
3651 
3652  return query;
3653 }
3654 
3656 {
3657  QString cardinputidTag(":SETCARDID");
3658  QString colTag(":SET" + GetColumnName().toUpper());
3659 
3660  QString query("cardid = " + cardinputidTag + ", " +
3661  GetColumnName() + " = " + colTag);
3662 
3663  bindings.insert(cardinputidTag, m_parent.getInputID());
3664  bindings.insert(colTag, user->GetDBValue());
3665 
3666  return query;
3667 }
3668 
3669 void CardInput::loadByID(int inputid)
3670 {
3671  id->setValue(inputid);
3672  externalInputSettings->Load(inputid);
3674 }
3675 
3676 void CardInput::loadByInput(int _cardid, QString _inputname)
3677 {
3678  MSqlQuery query(MSqlQuery::InitCon());
3679  query.prepare("SELECT cardid FROM capturecard "
3680  "WHERE cardid = :CARDID AND inputname = :INPUTNAME");
3681  query.bindValue(":CARDID", _cardid);
3682  query.bindValue(":INPUTNAME", _inputname);
3683 
3684  if (query.exec() && query.isActive() && query.next())
3685  {
3686  loadByID(query.value(0).toInt());
3687  }
3688 }
3689 
3691 {
3692  uint cardid = id->getValue().toUInt();
3693  QString init_input = CardUtil::GetInputName(cardid);
3696 
3697  uint icount = 1;
3698  if (instancecount)
3699  icount = instancecount->getValue().toUInt();
3700  vector<uint> cardids = CardUtil::GetChildInputIDs(cardid);
3701 
3702  // Delete old clone cards as required.
3703  for (uint i = cardids.size() + 1;
3704  (i > icount) && !cardids.empty(); --i)
3705  {
3706  CardUtil::DeleteCard(cardids.back());
3707  cardids.pop_back();
3708  }
3709 
3710  // Clone this config to existing clone cards.
3711  for (uint i = 0; i < cardids.size(); ++i)
3712  {
3713  CardUtil::CloneCard(cardid, cardids[i]);
3714  }
3715 
3716  // Create new clone cards as required.
3717  for (uint i = cardids.size() + 1; i < icount; i++)
3718  {
3719  CardUtil::CloneCard(cardid, 0);
3720  }
3721 
3722  // Delete any unused input groups
3724 }
3725 
3727 {
3728  return m_parent.getInputID();
3729 }
3730 
3732 {
3733  return m_parent.getCardID();
3734 }
3735 
3737 {
3738  listbox->setLabel(tr("Capture cards"));
3739  addChild(listbox);
3740 }
3741 
3743 {
3745  edit();
3746 
3747  return kDialogCodeRejected;
3748 }
3749 
3751 {
3753  listbox->addSelection(QObject::tr("(New capture card)"), "0");
3754  listbox->addSelection(QObject::tr("(Delete all capture cards on %1)")
3755  .arg(gCoreContext->GetHostName()), "-1");
3756  listbox->addSelection(QObject::tr("(Delete all capture cards)"), "-2");
3758 }
3759 
3761  const char* widgetName)
3762 {
3763  dialog = ConfigurationDialog::dialogWidget(parent, widgetName);
3764  connect(dialog, SIGNAL(menuButtonPressed()), this, SLOT(menu()));
3765  connect(dialog, SIGNAL(editButtonPressed()), this, SLOT(edit()));
3766  connect(dialog, SIGNAL(deleteButtonPressed()), this, SLOT(del()));
3767  return dialog;
3768 }
3769 
3771 {
3772  if (!listbox->getValue().toInt())
3773  {
3774  CaptureCard cc;
3775  cc.exec();
3776  }
3777  else
3778  {
3781  "",
3782  tr("Capture Card Menu"),
3783  tr("Edit..."),
3784  tr("Delete..."),
3786 
3787  if (kDialogCodeButton0 == val)
3788  edit();
3789  else if (kDialogCodeButton1 == val)
3790  del();
3791  }
3792 }
3793 
3795 {
3796  const int cardid = listbox->getValue().toInt();
3797  if (-1 == cardid)
3798  {
3800  GetMythMainWindow(), "",
3801  tr("Are you sure you want to delete "
3802  "ALL capture cards on %1?").arg(gCoreContext->GetHostName()),
3803  tr("Yes, delete capture cards"),
3804  tr("No, don't"), kDialogCodeButton1);
3805 
3806  if (kDialogCodeButton0 == val)
3807  {
3808  MSqlQuery cards(MSqlQuery::InitCon());
3809 
3810  cards.prepare(
3811  "SELECT cardid "
3812  "FROM capturecard "
3813  "WHERE hostname = :HOSTNAME");
3814  cards.bindValue(":HOSTNAME", gCoreContext->GetHostName());
3815 
3816  if (!cards.exec() || !cards.isActive())
3817  {
3820  tr("Error getting list of cards for this host"),
3821  tr("Unable to delete capturecards for %1")
3822  .arg(gCoreContext->GetHostName()));
3823 
3824  MythDB::DBError("Selecting cardids for deletion", cards);
3825  return;
3826  }
3827 
3828  while (cards.next())
3829  CardUtil::DeleteCard(cards.value(0).toUInt());
3830  }
3831  }
3832  else if (-2 == cardid)
3833  {
3835  GetMythMainWindow(), "",
3836  tr("Are you sure you want to delete "
3837  "ALL capture cards?"),
3838  tr("Yes, delete capture cards"),
3839  tr("No, don't"), kDialogCodeButton1);
3840 
3841  if (kDialogCodeButton0 == val)
3842  {
3844  Load();
3845  }
3846  }
3847  else
3848  {
3849  CaptureCard cc;
3850  if (cardid)
3851  cc.loadByID(cardid);
3852  cc.exec();
3853  }
3854 }
3855 
3857 {
3859  GetMythMainWindow(), "",
3860  tr("Are you sure you want to delete this capture card?"),
3861  tr("Yes, delete capture card"),
3862  tr("No, don't"), kDialogCodeButton1);
3863 
3864  if (kDialogCodeButton0 == val)
3865  {
3866  CardUtil::DeleteCard(listbox->getValue().toUInt());
3867  Load();
3868  }
3869 }
3870 
3872 {
3873  listbox->setLabel(tr("Video sources"));
3874  addChild(listbox);
3875 }
3876 
3878  const char* widgetName)
3879 {
3880  dialog = ConfigurationDialog::dialogWidget(parent, widgetName);
3881  connect(dialog, SIGNAL(menuButtonPressed()), this, SLOT(menu()));
3882  connect(dialog, SIGNAL(editButtonPressed()), this, SLOT(edit()));
3883  connect(dialog, SIGNAL(deleteButtonPressed()), this, SLOT(del()));
3884  return dialog;
3885 }
3886 
3888 {
3890  edit();
3891 
3892  return kDialogCodeRejected;
3893 }
3894 
3896 {
3898  listbox->addSelection(QObject::tr("(New video source)"), "0");
3899  listbox->addSelection(QObject::tr("(Delete all video sources)"), "-1");
3901 }
3902 
3904 {
3905  if (!listbox->getValue().toInt())
3906  {
3907  VideoSource vs;
3908  vs.exec();
3909  }
3910  else
3911  {
3914  "",
3915  tr("Video Source Menu"),
3916  tr("Edit..."),
3917  tr("Delete..."),
3919 
3920  if (kDialogCodeButton0 == val)
3921  edit();
3922  else if (kDialogCodeButton1 == val)
3923  del();
3924  }
3925 }
3926 
3928 {
3929  const int sourceid = listbox->getValue().toInt();
3930  if (-1 == sourceid)
3931  {
3933  GetMythMainWindow(), "",
3934  tr("Are you sure you want to delete "
3935  "ALL video sources?"),
3936  tr("Yes, delete video sources"),
3937  tr("No, don't"), kDialogCodeButton1);
3938 
3939  if (kDialogCodeButton0 == val)
3940  {
3942  Load();
3943  }
3944  }
3945  else
3946  {
3947  VideoSource vs;
3948  if (sourceid)
3949  vs.loadByID(sourceid);
3950  vs.exec();
3951  }
3952 }
3953 
3955 {
3957  GetMythMainWindow(), "",
3958  tr("Are you sure you want to delete "
3959  "this video source?"),
3960  tr("Yes, delete video source"),
3961  tr("No, don't"),
3963 
3964  if (kDialogCodeButton0 == val)
3965  {
3967  Load();
3968  }
3969 }
3970 
3972 {
3973  listbox->setLabel(tr("Input connections"));
3974  addChild(listbox);
3975 }
3976 
3978 {
3980  {
3981  if (!listbox)
3982  return kDialogCodeRejected;
3983 
3984  if (cardinputs.empty())
3985  return kDialogCodeRejected;
3986 
3987  int val = listbox->getValue().toInt();
3988 
3989  if (cardinputs[val])
3990  cardinputs[val]->exec();
3991  }
3992 
3993  return kDialogCodeRejected;
3994 }
3995 
3997 {
3998  cardinputs.clear();
4000 
4001  // We do this manually because we want custom labels. If
4002  // SelectSetting provided a facility to edit the labels, we
4003  // could use CaptureCard::fillSelections
4004 
4005  MSqlQuery query(MSqlQuery::InitCon());
4006  query.prepare(
4007  "SELECT cardid, videodevice, cardtype, inputname "
4008  "FROM capturecard "
4009  "WHERE hostname = :HOSTNAME "
4010  " AND parentid = 0 "
4011  "ORDER BY cardid");
4012  query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
4013 
4014  if (!query.exec())
4015  {
4016  MythDB::DBError("CardInputEditor::load", query);
4017  return;
4018  }
4019 
4020  uint j = 0;
4021  QMap<QString, uint> device_refs;
4022  while (query.next())
4023  {
4024  uint cardid = query.value(0).toUInt();
4025  QString videodevice = query.value(1).toString();
4026  QString cardtype = query.value(2).toString();
4027  QString inputname = query.value(3).toString();
4028 
4029  CardInput *cardinput = new CardInput(cardtype, videodevice,
4030  true, cardid);
4031  cardinput->loadByID(cardid);
4032  QString inputlabel = QString("%1 (%2) -> %3")
4033  .arg(CardUtil::GetDeviceLabel(cardtype, videodevice))
4034  .arg(inputname).arg(cardinput->getSourceName());
4035  cardinputs.push_back(cardinput);
4036  listbox->addSelection(inputlabel, QString::number(j++));
4037  }
4038 }
4039 
4040 #ifdef USING_DVB
4041 static QString remove_chaff(const QString &name)
4042 {
4043  // Trim off some of the chaff.
4044  QString short_name = name;
4045  if (short_name.startsWith("LG Electronics"))
4046  short_name = short_name.right(short_name.length() - 15);
4047  if (short_name.startsWith("Oren"))
4048  short_name = short_name.right(short_name.length() - 5);
4049  if (short_name.startsWith("Nextwave"))
4050  short_name = short_name.right(short_name.length() - 9);
4051  if (short_name.startsWith("frontend", Qt::CaseInsensitive))
4052  short_name = short_name.left(short_name.length() - 9);
4053  if (short_name.endsWith("VSB/QAM"))
4054  short_name = short_name.left(short_name.length() - 8);
4055  if (short_name.endsWith("VSB"))
4056  short_name = short_name.left(short_name.length() - 4);
4057  if (short_name.endsWith("DVB-T"))
4058  short_name = short_name.left(short_name.length() - 6);
4059 
4060  // It would be infinitely better if DVB allowed us to query
4061  // the vendor ID. But instead we have to guess based on the
4062  // demodulator name. This means cards like the Air2PC HD5000
4063  // and DViCO Fusion HDTV cards are not identified correctly.
4064  short_name = short_name.simplified();
4065  if (short_name.startsWith("or51211", Qt::CaseInsensitive))
4066  short_name = "pcHDTV HD-2000";
4067  else if (short_name.startsWith("or51132", Qt::CaseInsensitive))
4068  short_name = "pcHDTV HD-3000";
4069  else if (short_name.startsWith("bcm3510", Qt::CaseInsensitive))
4070  short_name = "Air2PC v1";
4071  else if (short_name.startsWith("nxt2002", Qt::CaseInsensitive))
4072  short_name = "Air2PC v2";
4073  else if (short_name.startsWith("nxt200x", Qt::CaseInsensitive))
4074  short_name = "Air2PC v2";
4075  else if (short_name.startsWith("lgdt3302", Qt::CaseInsensitive))
4076  short_name = "DViCO HDTV3";
4077  else if (short_name.startsWith("lgdt3303", Qt::CaseInsensitive))
4078  short_name = "DViCO v2 or Air2PC v3 or pcHDTV HD-5500";
4079 
4080  return short_name;
4081 }
4082 #endif // USING_DVB
4083 
4084 void DVBConfigurationGroup::reloadDiseqcTree(const QString &videodevice)
4085 {
4086  if (diseqc_tree)
4087  diseqc_tree->Load(videodevice);
4088 }
4089 
4090 void DVBConfigurationGroup::probeCard(const QString &videodevice)
4091 {
4092  if (videodevice.isEmpty())
4093  {
4094  cardname->setValue("");
4095  cardtype->setValue("");
4096  return;
4097  }
4098 
4099  if (parent.getCardID() && parent.GetRawCardType() != "DVB")
4100  {
4101  cardname->setValue("");
4102  cardtype->setValue("");
4103  return;
4104  }
4105 
4106 #ifdef USING_DVB
4107  QString frontend_name = CardUtil::ProbeDVBFrontendName(videodevice);
4108  QString subtype = CardUtil::ProbeDVBType(videodevice);
4109 
4110  QString err_open = tr("Could not open card %1").arg(videodevice);
4111  QString err_other = tr("Could not get card info for card %1").arg(videodevice);
4112 
4113  switch (CardUtil::toInputType(subtype))
4114  {
4115  case CardUtil::ERROR_OPEN:
4116  cardname->setValue(err_open);
4117  cardtype->setValue(strerror(errno));
4118  break;
4120  cardname->setValue(err_other);
4121  cardtype->setValue("Unknown error");
4122  break;
4123  case CardUtil::ERROR_PROBE:
4124  cardname->setValue(err_other);
4125  cardtype->setValue(strerror(errno));
4126  break;
4127  case CardUtil::QPSK:
4128  cardtype->setValue("DVB-S");
4129  cardname->setValue(frontend_name);
4130  signal_timeout->setValue(7000);
4131  channel_timeout->setValue(10000);
4132  break;
4133  case CardUtil::DVBS2:
4134  cardtype->setValue("DVB-S2");
4135  cardname->setValue(frontend_name);
4136  signal_timeout->setValue(7000);
4137  channel_timeout->setValue(10000);
4138  break;
4139  case CardUtil::QAM:
4140  cardtype->setValue("DVB-C");
4141  cardname->setValue(frontend_name);
4142  signal_timeout->setValue(1000);
4143  channel_timeout->setValue(3000);
4144  break;
4145  case CardUtil::DVBT2:
4146  cardtype->setValue("DVB-T2");
4147  cardname->setValue(frontend_name);
4148  signal_timeout->setValue(1000);
4149  channel_timeout->setValue(3000);
4150  break;
4151  case CardUtil::OFDM:
4152  {
4153  cardtype->setValue("DVB-T");
4154  cardname->setValue(frontend_name);
4155  signal_timeout->setValue(1000);
4156  channel_timeout->setValue(3000);
4157  if (frontend_name.toLower().indexOf("usb") >= 0)
4158  {
4159  signal_timeout->setValue(40000);
4160  channel_timeout->setValue(42500);
4161  }
4162 
4163  // slow down tuning for buggy drivers
4164  if ((frontend_name == "DiBcom 3000P/M-C DVB-T") ||
4165  (frontend_name ==
4166  "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"))
4167  {
4168  tuning_delay->setValue(200);
4169  }
4170 
4171 #if 0 // frontends on hybrid DVB-T/Analog cards
4172  QString short_name = remove_chaff(frontend_name);
4173  buttonAnalog->setVisible(
4174  short_name.startsWith("zarlink zl10353",
4175  Qt::CaseInsensitive) ||
4176  short_name.startsWith("wintv hvr 900 m/r: 65008/a1c0",
4177  Qt::CaseInsensitive) ||
4178  short_name.startsWith("philips tda10046h",
4179  Qt::CaseInsensitive));
4180 #endif
4181  }
4182  break;
4183  case CardUtil::ATSC:
4184  {
4185  QString short_name = remove_chaff(frontend_name);
4186  cardtype->setValue("ATSC");
4187  cardname->setValue(short_name);
4188  signal_timeout->setValue(500);
4189  channel_timeout->setValue(3000);
4190 
4191  // According to #1779 and #1935 the AverMedia 180 needs
4192  // a 3000 ms signal timeout, at least for QAM tuning.
4193  if (frontend_name == "Nextwave NXT200X VSB/QAM frontend")
4194  {
4195  signal_timeout->setValue(3000);
4196  channel_timeout->setValue(5500);
4197  }
4198 
4199 #if 0 // frontends on hybrid DVB-T/Analog cards
4200  if (frontend_name.toLower().indexOf("usb") < 0)
4201  {
4202  buttonAnalog->setVisible(
4203  short_name.startsWith("pchdtv", Qt::CaseInsensitive) ||
4204  short_name.startsWith("dvico", Qt::CaseInsensitive) ||
4205  short_name.startsWith("nextwave", Qt::CaseInsensitive));
4206  }
4207 #endif
4208  }
4209  break;
4210  default:
4211  break;
4212  }
4213 #else
4214  cardtype->setValue(QString("Recompile with DVB-Support!"));
4215 #endif
4216 }
4217 
4219  QString dev, QString type) :
4220  ComboBoxSetting(this), CaptureCardDBStorage(this, parent, "audiodevice"),
4221  last_device(dev), last_cardtype(type)
4222 {
4223  setLabel(QObject::tr("Audio input"));
4224  setHelpText(QObject::tr("If there is more than one audio input, "
4225  "select which one to use."));
4226  int cardid = parent.getCardID();
4227  if (cardid <= 0)
4228  return;
4229 
4232 }
4233 
4234 void TunerCardAudioInput::fillSelections(const QString &device)
4235 {
4236  clearSelections();
4237 
4238  if (device.isEmpty())
4239  return;
4240 
4241  last_device = device;
4242  QStringList inputs =
4244 
4245  for (uint i = 0; i < (uint)inputs.size(); i++)
4246  {
4247  addSelection(inputs[i], QString::number(i),
4248  last_device == QString::number(i));
4249  }
4250 }
4251 
4253 {
4254  public:
4256 };
4257 
4259 {
4261  rec->setLabel(QObject::tr("Recorder Options"));
4262  rec->setUseLabel(false);
4263 
4264  rec->addChild(new DVBNoSeqStart(parent.parent));
4265  rec->addChild(new DVBOnDemand(parent.parent));
4266  rec->addChild(new DVBEITScan(parent.parent));
4267  rec->addChild(new DVBTuningDelay(parent.parent));
4268 
4269  addChild(rec);
4270 }
4271 
4274  parent(a_parent),
4275  diseqc_tree(new DiSEqCDevTree())
4276 {
4277  cardnum = new DVBCardNum(parent);
4278  cardname = new DVBCardName();
4279  cardtype = new DVBCardType();
4280 
4281  signal_timeout = new SignalTimeout(parent, 500, 250);
4282  channel_timeout = new ChannelTimeout(parent, 3000, 1750);
4283 
4284  addChild(cardnum);
4285 
4287  new HorizontalConfigurationGroup(false, false, true, true);
4288  hg0->addChild(cardname);
4289  hg0->addChild(cardtype);
4290  addChild(hg0);
4291 
4294 
4297 
4298  TransButtonSetting *buttonRecOpt = new TransButtonSetting();
4299  buttonRecOpt->setLabel(tr("Recording Options"));
4300 
4302  new HorizontalConfigurationGroup(false, false, true, true);
4303  advcfg->addChild(buttonRecOpt);
4304  addChild(advcfg);
4305 
4307  diseqc_btn->setLabel(tr("DiSEqC (Switch, LNB, and Rotor Configuration)"));
4308  diseqc_btn->setHelpText(tr("Input and satellite settings."));
4309 
4310  HorizontalConfigurationGroup *diseqc_cfg =
4311  new HorizontalConfigurationGroup(false, false, true, true);
4312  diseqc_cfg->addChild(diseqc_btn);
4313  diseqc_btn->setVisible(false);
4314  addChild(diseqc_cfg);
4315 
4318  tuning_delay->setVisible(false);
4319 
4320  connect(cardnum, SIGNAL(valueChanged(const QString&)),
4321  this, SLOT( probeCard (const QString&)));
4322  connect(cardnum, SIGNAL(valueChanged(const QString&)),
4323  this, SLOT( reloadDiseqcTree(const QString&)));
4324  connect(diseqc_btn, SIGNAL(pressed()),
4325  this, SLOT( DiSEqCPanel()));
4326  connect(buttonRecOpt, SIGNAL(pressed()),
4327  this, SLOT( DVBExtraPanel()));
4328 }
4329 
4331 {
4332  if (diseqc_tree)
4333  {
4334  delete diseqc_tree;
4335  diseqc_tree = NULL;
4336  }
4337 }
4338 
4340 {
4341  parent.reload(); // ensure card id is valid
4342 
4343  DTVDeviceTreeWizard diseqcWiz(*diseqc_tree);
4344  diseqcWiz.exec();
4345 }
4346 
4348 {
4351  if (cardtype->getValue() == "DVB-S" ||
4352  cardtype->getValue() == "DVB-S2" ||
4354  {
4355  diseqc_btn->setVisible(true);
4356  }
4357 }
4358 
4360 {
4363  DiSEqCDev trees;
4364  trees.InvalidateTrees();
4365 }
4366 
4368 {
4369  parent.reload(); // ensure card id is valid
4370 
4371  DVBExtra acw(*this);
4372  acw.exec();
4373 }
void SetOldValue(const QString &s)
Definition: videosource.h:932
V4L2encGroup(CaptureCard &parent)
virtual void setValue(const QString &newValue)
Definition: settings.cpp:96
QStringList grabberArgs
Definition: videosource.h:179
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:785
TransButtonSetting * scan
Definition: videosource.h:891
HDHomeRunIP * _cardip
Definition: videosource.h:967
DataDirectUserID(const VideoSource &parent)
VBoxExtra(VBoxConfigurationGroup &parent)
QuickTune(const CardInput &parent)
void UpdateDevices(const QString &)
void Run(time_t timeout=0)
Runs a command inside the /bin/sh shell. Returns immediately.
static bool IsTunerSharingCapable(const QString &rawtype)
Definition: cardutil.h:163
virtual void Load(void)
static QString remove_chaff(const QString &name)
void SetSourceID(uint _sourceid)
virtual void Load(void)
virtual void clearSelections(void)
Definition: settings.cpp:175
void setVisible(bool b)
Definition: settings.h:65
static QStringList ProbeVideoDevices(const QString &rawtype)
Definition: cardutil.cpp:348
virtual void setEnabled(bool e)
TransLabelSetting * cardinfo
Definition: videosource.h:490
virtual void setValue(bool check)
Definition: settings.h:434
void bindValue(const QString &placeholder, const QVariant &val)
Definition: mythdbcon.cpp:884
DiSEqCDevSettings * externalInputSettings
Definition: videosource.h:893
vector< CardInput * > cardinputs
Definition: videosource.h:830
Definition: cc.h:13
QString getSourceName(void) const
Definition: videosource.h:237
static ChannelInfoList GetAllChannels(uint sourceid)
Returns channels that are not connected to an input and channels that are not marked as visible...
Definition: channelutil.h:244
DVB-S device settings class.
Definition: diseqc.h:37
TransButtonSetting * srcfetch
Definition: videosource.h:892
QString _tuner
Definition: videosource.h:1125
def scan(profile, smoonURL, gate)
Definition: scan.py:43
static QString GetInputName(uint inputid)
Definition: cardutil.cpp:1046
void fillSelections()
CaptureCard & parent
Definition: videosource.h:469
void valueChanged(const QString &)
virtual DialogCode exec(void)
virtual void Load(void)
QString Card(void) const
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:83
allow access to stdout
Definition: mythsystem.h:39
virtual void Save(void)
static QStringList GetVideoDevices(const QString &rawtype, QString hostname=QString::null)
Returns the videodevices of the matching inputs, duplicates removed.
Definition: cardutil.cpp:305
virtual MythDialog * dialogWidget(MythMainWindow *parent, const char *widgetName=0)
VideoDevice(const CaptureCard &parent, uint minor_min=0, uint minor_max=UINT_MAX, QString card=QString::null, QString driver=QString::null)
virtual void Load(void)
virtual void Load(void)
virtual void Save(void)
QString cardip
Definition: videosource.h:421
void probeCard(const QString &device)
HDHomeRunDeviceIDList(HDHomeRunDeviceID *deviceid, TransLabelSetting *desc, HDHomeRunIP *cardip, HDHomeRunTunerIndex *cardtuner, HDHomeRunDeviceList *devicelist)
virtual void Save(void)
void setProgress(int curprogress)
virtual void setEnabled(bool b)
Definition: settings.cpp:688
CardType(const CaptureCard &parent)
static uint CreateInputGroup(const QString &name)
Definition: cardutil.cpp:1211
void probeCard(const QString &device)
virtual void deleteLater(void)
static QString ProbeDVBType(const QString &device)
Definition: cardutil.cpp:457
static DialogCode Show2ButtonPopup(MythMainWindow *parent, const QString &title, const QString &message, const QString &button1msg, const QString &button2msg, DialogCode default_button)
void SetSourceID(const QString &sourceid)
virtual QString getSelectionLabel(void) const
Definition: settings.cpp:213
TunerCardAudioInput(const CaptureCard &parent, QString dev=QString::null, QString type=QString::null)
EITOnly_config(const VideoSource &_parent)
ASIDevice(const CaptureCard &parent)
AudioRateLimit(const CaptureCard &parent)
virtual void Load(void)
NoGrabber_config(const VideoSource &_parent)
static uint GetChannelCount(uint sourceid)
Definition: sourceutil.cpp:109
bool visible
Definition: settings.h:91
uint modelid
Definition: avcinfo.h:44
SignalTimeout(const CaptureCard &parent, uint value, uint min_val)
static QString GetDeviceLabel(const QString &inputtype, const QString &videodevice)
Definition: cardutil.cpp:1795
static void error(const char *str,...)
Definition: vbi.c:41
static bool DeleteSource(uint sourceid)
Definition: sourceutil.cpp:479
SpinBoxSetting * instancecount
Definition: videosource.h:896
SchedGroup(const CardInput &parent)
virtual int getValueIndex(QString value)
Returns index of value in SelectSetting, or -1 if not found.
Definition: settings.cpp:224
virtual void setVisible(bool b)
Definition: settings.cpp:695
CetonDeviceID * deviceid
Definition: videosource.h:471
static enum INPUT_TYPES toInputType(const QString &name)
Definition: cardutil.h:74
TransLabelSetting * desc
Definition: videosource.h:470
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
ScheduleOrder(const CardInput &parent, int _value)
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)
virtual QString GetWhereClause(MSqlBindings &bindings) const
static QString ProbeDVBFrontendName(const QString &device)
Returns the input type from the video device.
Definition: cardutil.cpp:507
LiveTVOrder(const CardInput &parent, int _value)
void setName(const QString &str)
Definition: settings.h:47
virtual void Load(void)
DVBExtra(DVBConfigurationGroup &parent)
QString _overridedeviceid
Definition: videosource.h:991
static bool IsInNeedOfExternalInputConf(uint inputid)
Definition: cardutil.cpp:1475
QString label
Definition: settings.h:89
CheckBoxSetting * schedgroup
Definition: videosource.h:897
int size(void) const
Definition: mythdbcon.h:187
QString deviceid
Definition: videosource.h:419
static bool IsUnscanable(const QString &rawtype)
Definition: cardutil.h:145
bool cardTypesInclude(const int &SourceID, const QString &thecardtype)
InputGroup(const CardInput &parent, uint group_num)
FirewireModel(const CaptureCard &parent, const FirewireGUID *)
DVBEITScan(const CaptureCard &parent)
CaptureCard & parent
Definition: videosource.h:450
virtual void addChild(Configurable *child)
virtual DialogCode exec(void)
voidpf void uLong size
Definition: ioapi.h:136
bool IsOpen(void) const
Definition: v4l2util.h:29
void CreateNewInputGroup()
virtual void setEnabled(bool e)
HDHomeRunDeviceList * _devicelist
Definition: videosource.h:969
InputDisplayName(const CardInput &parent)
ChannelTimeout * channel_timeout
Definition: videosource.h:649
const char * filename
Definition: ioapi.h:135
virtual void setValue(const QString &newValue)
Definition: settings.cpp:707
unsigned int uint
Definition: compat.h:136
int getCardID(void) const
Definition: videosource.h:704
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
TransLabelSetting * cardinfo
Definition: videosource.h:564
unsigned current
Definition: settings.h:311
SourceID * sourceid
Definition: videosource.h:889
V4LConfigurationGroup(CaptureCard &parent)
QString product_name
Definition: avcinfo.h:46
TransLabelSetting * info
Definition: videosource.h:595
DataDirectPassword * password
Definition: videosource.h:155
IPTVHost(const CaptureCard &parent)
QString getSourceName(void) const
CetonDeviceID(const CaptureCard &parent)
virtual DialogCode exec(void)
VBoxConfigurationGroup(CaptureCard &parent)
__u32 index
Definition: videodev2.h:1039
HDHomeRunDeviceID * _deviceid
Definition: videosource.h:965
ListBoxSetting * listbox
Definition: videosource.h:831
TransLabelSetting * cardinfo
Definition: videosource.h:511
static void SortChannels(ChannelInfoList &list, const QString &order, bool eliminate_duplicates=false)
QMap< QString, VBoxDevice > VBoxDeviceList
Definition: videosource.h:428
VideoSourceSelector(uint _initial_sourceid, const QString &_card_types, bool _must_have_mplexid)
Definition: videosource.cpp:62
void UpdateDevices(const QString &)
virtual void setEnabled(bool e)
CaptureCard & parent
Definition: videosource.h:489
bool ProbeCard(HDHomeRunDevice &)
InputGroup * inputgrp0
Definition: videosource.h:894
void probeApp(const QString &path)
QMap< QString, HDHomeRunDevice > HDHomeRunDeviceList
Definition: videosource.h:383
static bool HasTuner(const QString &rawtype, const QString &device)
Definition: cardutil.cpp:158
DVBTuningDelay(const CaptureCard &parent)
bool Load(uint card_input_id)
Loads configuration chain from DB for specified card input id.
Definition: diseqc.cpp:137
virtual MythDialog * dialogWidget(MythMainWindow *parent, const char *widgetName=0)
bool Store(uint cardid, const QString &device="")
Stores the device tree to the database.
Definition: diseqc.cpp:434
virtual void Save(void)
__u32 type
Definition: videodev2.h:1038
virtual void Load(void)
void SetOldValue(const QString &s)
Definition: videosource.h:911
void probeCard(const QString &device)
virtual void Load(void)
Definition: videosource.cpp:74
void fillSelections(const QString &current)
Adds all available cards to list If current is >= 0 it will be considered available even if no device...
static bool GetV4LInfo(int videofd, QString &input, QString &driver, uint32_t &version, uint32_t &capabilities)
Definition: cardutil.cpp:1522
virtual void addChild(Configurable *child)
CaptureCard & parent
Definition: videosource.h:643
void LoadedTuner(const QString &)
void UpdateDevices(const QString &)
virtual void setHelpText(const QString &str)
Definition: settings.h:61
virtual void addSelection(const QString &label, QString value=QString::null, bool select=false)
Definition: settings.cpp:843
void SetTuner(const QString &)
const char * name
Definition: frequencies.h:102
static bool IsEncoder(const QString &rawtype)
Definition: cardutil.h:123
DVBConfigurationGroup(CaptureCard &a_parent)
virtual void setLabel(QString)
Definition: settings.cpp:1194
ExternalConfigurationGroup(CaptureCard &parent)
QString deviceid
Definition: videosource.h:375
void fillSelections(const QString &current)
Adds all available cards to list If current is >= 0 it will be considered available even if no device...
virtual void Load(void)
static void fillSelections(SelectSetting *setting)
QString GetConfDir(void)
Definition: mythdirs.cpp:212
void addSelection(const QString &label, QString value=QString::null, bool select=false)
Definition: settings.cpp:1018
QVariant value(int i) const
Definition: mythdbcon.h:182
void loadByID(int id)
void probeCard(const QString &device)
FirewireConfigurationGroup(CaptureCard &a_parent)
void removeTarget(QString triggerValue)
VBoxTunerIndex * _cardtuner
Definition: videosource.h:1062
void sourceFetch()
static QString GetVBoxdesc(const QString &id, const QString &ip, const QString &tunerNo, const QString &tunerType)
Get a nicely formatted string describing the device.
Definition: cardutil.cpp:2191
CaptureCard(bool use_card_group=true)
DDLineupList GetLineups(void) const
Definition: datadirect.h:343
static bool showGetTextPopup(MythMainWindow *parent, QString title, QString message, QString &text)
virtual void Load(void)
Definition: mythstorage.cpp:7
QString cardtuner
Definition: videosource.h:378
void SetTuner(const QString &)
DataDirectLineupSelector * lineupselector
Definition: videosource.h:157
static vector< AVCInfo > GetSTBList(void)
void UpdateSchedGroup(int value)
DataDirect_config(const VideoSource &_parent, int _ddsource)
const FirewireGUID * guid
Definition: videosource.h:670
QMap< QString, Configurable * > triggerMap
SourceID(const CardInput &parent)
static QStringList ProbeAudioInputs(QString device, QString inputtype=QString::null)
Definition: cardutil.cpp:1698
struct CHANLISTS chanlists[]
const char * name
Definition: ParseText.cpp:338
void loadByInput(int cardid, QString input)
virtual void setEnabled(bool b)
Definition: settings.cpp:1187
static QString TestMimeType(const QString &sFileName)
void fillSelections()
virtual QString GetValue(uint i) const
Definition: settings.h:289
void SetIP(const QString &)
DialogCode
Definition: mythdialogs.h:21
virtual void addSelection(const QString &label, QString value=QString::null, bool select=false)
Definition: settings.cpp:115
void probeCard(const QString &device)
int errno
TunerCardAudioInput * audioinput
Definition: videosource.h:527
FileDevice(const CaptureCard &parent)
int getCardID(void) const
void fillSelections(const QString &current)
Adds all available device-tuner combinations to list.
void LoadedIP(const QString &)
InputName(const CardInput &parent)
void SetOldValue(const QString &s)
Definition: videosource.h:1006
virtual void Load(void)
QMap< uint, uint > minor_list
AudioDevice(const CaptureCard &parent)
run process through shell
Definition: mythsystem.h:41
TransLabelSetting * m_cardinfo
Definition: videosource.h:542
bool isEnabled()
Definition: settings.h:69
virtual void setEnabled(bool e)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
QString GetSetting(const QString &key, const QString &defaultval="")
CaptureCard & parent
Definition: videosource.h:508
QByteArray & ReadAll()
static QString GetDeviceName(dvb_dev_type_t, const QString &device)
Definition: cardutil.cpp:2077
static bool IsCableCardPresent(uint inputid, const QString &inputType)
Definition: cardutil.cpp:114
static uint GetDeviceInputGroup(uint inputid)
Definition: cardutil.cpp:1265
TransFreqTableSelector(uint _sourceid)
XMLTVGrabber * grabber
Definition: videosource.h:221
void UpdateDevices(const QString &)
__u64 val
Definition: videodev2.h:1041
TransButtonSetting * diseqc_btn
Definition: videosource.h:655
static void fillSelections(SelectSetting *setting)
DishNetEIT(const CardInput &parent)
bool isActive(void) const
Definition: mythdbcon.h:188
virtual void Save(void)
QString Driver(void) const
virtual void Load(void)
QString tunertype
Definition: videosource.h:423
CetonSetting * tuner
Definition: videosource.h:473
DataDirectButton * button
Definition: videosource.h:156
void SetGUID(const QString &)
VBoxDeviceID * _deviceid
Definition: videosource.h:1059
TransLabelSetting * cardinfo
Definition: videosource.h:526
bool Store(uint card_input_id) const
Stores configuration chain to DB for specified card input id.
Definition: diseqc.cpp:171
ASIConfigurationGroup(CaptureCard &parent)
bool discovered
Definition: videosource.h:425
void SetTuner(const QString &)
CaptureCard & parent
Definition: videosource.h:525
virtual void Save(void)
VBoxDeviceID(const CaptureCard &parent)
TransLabelSetting * _desc
Definition: videosource.h:966
void SetGUID(const QString &)
virtual QString GetWhereClause(MSqlBindings &bindings) const
QString mythdeviceid
Definition: videosource.h:374
static vector< uint > GetChildInputIDs(uint inputid)
Definition: cardutil.cpp:706
static bool UnlinkInputGroup(uint inputid, uint inputgroupid)
Definition: cardutil.cpp:1329
virtual void Load(void)
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:542
static QString GetModelName(uint vendorid, uint modelid)
void LoadValue(const QString &)
uint vendorid
Definition: avcinfo.h:43
XMLTVConfig(const VideoSource &aparent)
QString _overridedeviceid
Definition: videosource.h:1085
virtual void Load(void)
AVCInfo GetAVCInfo(const QString &guid) const
SignalTimeout * signal_timeout
Definition: videosource.h:648
virtual void Save(void)
TransLabelSetting * info
Definition: videosource.h:579
virtual void triggerChanged(const QString &value)
FirewireConnection(const CaptureCard &parent)
CetonConfigurationGroup(CaptureCard &parent)
virtual DialogCode exec(void)
DVBCardName * cardname
Definition: videosource.h:646
void addSelection(const QString &label, QString value=QString::null, bool select=false)
Definition: settings.cpp:733
IPTVConfigurationGroup(CaptureCard &a_parent)
const CardInput & cardinput
static int GetASIDeviceNumber(const QString &device, QString *error=NULL)
Definition: cardutil.cpp:2263
CaptureCard & m_parent
Definition: videosource.h:541
static bool CloneCard(uint src_inputid, uint dst_inputid)
Definition: cardutil.cpp:883
ListBoxSetting * listbox
Definition: videosource.h:783
CetonSetting(const char *label, const char *helptext)
A ConfigurationDialog that uses a ConfigurationGroup with one child per page.
Base dialog for most dialogs in MythTV using the old UI.
Definition: mythdialogs.h:50
virtual void Load(void)
void fillDataDirectLineupSelector(void)
MPEGConfigurationGroup(CaptureCard &parent)
DVBOnDemand(const CaptureCard &parent)
InputPriority(const CardInput &parent)
MythMainWindow * GetMythMainWindow(void)
virtual void Save(void)
Definition: mythstorage.cpp:83
uint Wait(time_t timeout=0)
virtual void setEnabled(bool b)
Definition: settings.cpp:342
void SetIP(const QString &)
virtual void triggerChanged(const QString &value)
static bool showOkPopup(MythMainWindow *parent, const QString &title, const QString &message, QString button_msg=QString())
XMLTV_generic_config(const VideoSource &_parent, QString _grabber)
vector< ChannelInfo > ChannelInfoList
Definition: channelinfo.h:121
void SetIP(const QString &)
static const uint kDefaultMultirecCount
Definition: videosource.cpp:60
static QString GetVideoDevice(uint inputid)
Definition: cardutil.h:273
void LoadXMLTVGrabbers(QStringList name_list, QStringList prog_list)
ImportConfigurationGroup(CaptureCard &parent)
virtual void Save(void)
virtual void Save(QString)
virtual void Load(void)
DataDirectUserID * userid
Definition: videosource.h:154
InputGroup * inputgrp1
Definition: videosource.h:895
VERBOSE_PREAMBLE Most Errors or other very important messages true
Definition: verbosedefs.h:91
void UpdateDevices(const QString &)
DiSEqCDevTree * diseqc_tree
Definition: videosource.h:654
__u32 id
Definition: videodev2.h:1038
virtual void clearSelections(void)
Definition: settings.cpp:1011
virtual void Save(void)
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:810
QString tunerno
Definition: videosource.h:422
struct v4l2_dbg_match match
Definition: videodev2.h:1038
static void fillSelections(SelectSetting *setting)
DataDirectPassword(const VideoSource &parent)
SkipBtAudio(const CaptureCard &parent)
CardInput(const QString &cardtype, const QString &device, bool is_new_input, int cardid)
VideoDevice * device
Definition: videosource.h:509
CaptureCard & parent
Definition: videosource.h:594
const VideoSource & parent
Definition: videosource.h:220
HDHomeRunDeviceID(const CaptureCard &parent)
virtual void triggerChanged(const QString &value)
UseEIT(const VideoSource &parent)
VerticalConfigurationGroup(bool luselabel=true, bool luseframe=true, bool lzeroMargin=false, bool lzeroSpace=false)
CaptureCardGroup(CaptureCard &parent)
void probeCard(const QString &cardNumber)
vector< DataDirectLineup > DDLineupList
Definition: datadirect.h:299
QString card_name
static QString GetAudioDevice(uint inputid)
Definition: cardutil.h:275
static bool Exists(int id)
Check if a Diseqc device tree exists.
Definition: diseqc.cpp:406
QString GetListingsProviderName(void) const
Definition: datadirect.h:351
HDHomeRunExtra(HDHomeRunConfigurationGroup &parent)
QMap< QString, AVCInfo > guid_to_avcinfo
void SetOldValue(const QString &s)
Definition: videosource.h:1027
void fillSelections(const QString &device)
InstanceCount(const CardInput &parent, int _initValue)
virtual uint size(void) const
Definition: settings.h:285
QString m_DriverName
Definition: videosource.h:544
virtual DialogCode exec(bool saveOnExec=false, bool doLoad=false)
virtual void setHelpText(const QString &str)
Definition: settings.cpp:793
DVBNetID(const VideoSource &parent, signed int value, signed int min_val)
void probeCard(const QString &device)
static bool DeleteAllSources(void)
Definition: sourceutil.cpp:531
HDPVRConfigurationGroup(CaptureCard &parent)
TransLabelSetting * _desc
Definition: videosource.h:1060
StartingChannel * startchan
Definition: videosource.h:890
void channelScanner()
virtual void setLabel(QString str)
Definition: settings.h:57
virtual DialogCode exec(bool saveOnExec=true, bool doLoad=true)
ListBoxSetting * listbox
Definition: videosource.h:812
static bool UpdateChannelsFromListings(uint sourceid, QString inputtype=QString::null, bool wait=false)
Definition: sourceutil.cpp:362
void SetOverrideDeviceID(const QString &)
virtual QString getValue(void) const
Definition: settings.cpp:91
DVBCardNum * cardnum
Definition: videosource.h:645
virtual QString GetSetClause(MSqlBindings &bindings) const
DVBNoSeqStart(const CaptureCard &parent)
void loadByID(int id)
void UpdateDevices(const QString &)
void InvalidateTrees(void)
Invalidate cached trees.
Definition: diseqc.cpp:256
ChannelTimeout(const CaptureCard &parent, uint value, uint min_val)
VBoxDeviceList * _devicelist
Definition: videosource.h:1063
XMLTVGrabber(const VideoSource &parent)
void setUseLabel(bool useit)
DVBCardType * cardtype
Definition: videosource.h:647
void probeCard(const QString &device)
DemoConfigurationGroup(CaptureCard &parent)
virtual void Load(void)
VBIDevice(const CaptureCard &parent)
static bool DeleteCard(uint inputid)
Definition: cardutil.cpp:1927
void reload(void)
HDHomeRunTunerIndex * _cardtuner
Definition: videosource.h:968
virtual void setVisible(bool b)
Definition: settings.cpp:918
static QString GetRawInputType(uint inputid)
Definition: cardutil.h:271
void setTrigger(Configurable *_trigger)
void fillSelections(const QString &current)
Adds all available device-tuner combinations to list If current is >= 0 it will be considered availab...
void fillSelectionsFromDir(const QDir &dir, bool absPath=true)
bool GrabLineupsOnly(void)
void UpdateDevices(const QString &)
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:98
ExternalChannelCommand(const CardInput &parent)
int getSourceID(void) const
Definition: videosource.h:230
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:610
virtual QString GetSetClause(MSqlBindings &bindings) const
VBoxDeviceIDList(VBoxDeviceID *deviceid, TransLabelSetting *desc, VBoxIP *cardip, VBoxTunerIndex *cardtuner, VBoxDeviceList *devicelist)
virtual void setSaveAll(bool b)
static bool GetListingsLoginData(uint sourceid, QString &grabber, QString &userid, QString &passwd, QString &lineupid)
Definition: sourceutil.cpp:144
QString helptext
Definition: settings.h:90
int getInputID(void) const
static bool LinkInputGroup(uint inputid, uint inputgroupid)
Definition: cardutil.cpp:1289
FirewireGUID(const CaptureCard &parent)
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:181
void reloadDiseqcTree(const QString &device)
virtual void Load(void)
FirewireSpeed(const CaptureCard &parent)
uint fillSelectionsFromDir(const QDir &dir, uint minor_min, uint minor_max, QString card, QString driver, bool allow_duplicates)
DVBTuningDelay * tuning_delay
Definition: videosource.h:653
virtual QString GetWhereClause(MSqlBindings &bindings) const
QString desc
Definition: videosource.h:420
void fillSelectionsFromDir(const QDir &dir, bool absPath=true)
ArgumentString(const CaptureCard &parent)
virtual void setHelpText(const QString &)
Definition: settings.cpp:1201
virtual void Save()
static bool DeleteAllCards(void)
Definition: cardutil.cpp:2003
QString GetRawCardType(void) const
QString GetHostName(void)
QString driver_name
virtual QString GetSetClause(MSqlBindings &bindings) const
QString _tuner
Definition: videosource.h:1084
DVBCardNum(const CaptureCard &parent)
bool HasSlicedVBI(void) const
Definition: v4l2util.cpp:131
const VideoSource & parent
Definition: videosource.h:153
DVB-S device tree class.
Definition: diseqc.h:75
uint fillSelectionsFromDir(const QDir &dir, const QString &card, const QString &driver)
QString DriverName(void) const
Definition: v4l2util.h:45
InputName * inputname
Definition: videosource.h:888
void setFilter(const QString &card, const QString &driver)
TransLabelSetting * info
Definition: videosource.h:612
QString CardName(void) const
Definition: v4l2util.h:46
const VideoSource & parent
Definition: videosource.h:177
UseEIT * useeit
Definition: videosource.h:191
void SetSourceID(const QString &sourceid)
HDHomeRunConfigurationGroup(CaptureCard &parent)
PresetTuner(const CardInput &parent)
__s32 value
Definition: videodev2.h:1042
static QString GetHDHRdesc(const QString &device)
Get a nicely formatted string describing the device.
Definition: cardutil.cpp:2134
CaptureCard & parent
Definition: videosource.h:562
void SetOverrideDeviceID(const QString &)
static bool is_grabber_external(const QString &grabber)
Definition: videosource.h:25
static void fillSelectionsFromDir(const QDir &dir, AudioOutput::ADCVect *list)
virtual void Save(void)
void fillSelections(const QString &uid, const QString &pwd, int source)
static uint CreateDeviceInputGroup(uint inputid, const QString &type, const QString &host, const QString &device)
Definition: cardutil.cpp:1253
static QString GetStartingChannel(uint inputid)
Definition: cardutil.cpp:1053
QString mythdeviceid
Definition: videosource.h:418
int getInputID(void) const
Definition: videosource.h:860
Main DVB-S device interface.
Definition: diseqc.h:52
static void GetDeviceInputNames(uint inputid, const QString &device, const QString &inputtype, QStringList &inputs)
Definition: cardutil.cpp:1818
virtual MythDialog * dialogWidget(MythMainWindow *parent, const char *widgetName)
virtual void Load(void)
FreqTableSelector(const VideoSource &parent)
void addChild(Configurable *child)
void addTarget(QString triggerValue, Configurable *target)
virtual void Load(void)
virtual void setEnabled(bool b)
Definition: settings.cpp:940
void loadByID(int id)