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