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